@suveren/gateway 0.11.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -1
- package/bin/suveren-gateway.js +137 -12
- package/content/integrations/calendar.json +1 -0
- package/content/integrations/crm.json +1 -67
- package/content/integrations/deploy-github.json +3 -5
- package/content/integrations/erp.json +1 -80
- package/content/integrations/gmail.json +1 -0
- package/content/integrations/linkedin.json +1 -0
- package/content/integrations/mail.json +1 -48
- package/content/integrations/mollie.json +1 -0
- package/content/integrations/records.json +1 -0
- package/dist/control-plane/index.mjs +555 -122
- package/dist/mcp-server/http.mjs +643 -168
- package/dist/ui/assets/{index-BzcgeHlq.js → index-CmLqzgqA.js} +21 -21
- package/dist/ui/assets/{index-BFOprnFZ.css → index-y1OFeYnS.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/lib/autostart-templates.d.mts +6 -0
- package/lib/autostart-templates.mjs +21 -4
- package/lib/config.d.mts +10 -0
- package/lib/config.mjs +79 -18
- package/lib/node-version.d.mts +7 -0
- package/lib/node-version.mjs +28 -0
- package/lib/policy.d.mts +34 -0
- package/lib/policy.mjs +369 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js +9 -7
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.js +17 -4
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js +23 -10
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationFormExample.js +63 -20
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationFormExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationUrlExample.js +71 -29
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationUrlExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/jsonResponseStreamableHttp.js +45 -6
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/jsonResponseStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleStreamableHttp.js +71 -31
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleTaskInteractive.js +61 -18
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleTaskInteractive.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js +57 -19
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/ssePollingExample.js +64 -17
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/ssePollingExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js +61 -13
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.d.ts +4 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.d.ts +17 -8
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.js +31 -14
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.d.ts +9 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.js +17 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.d.ts +12 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js +46 -2
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js +39 -9
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.d.ts +10 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.js +77 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js +9 -7
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js +18 -5
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js +24 -11
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationFormExample.js +63 -20
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationFormExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationUrlExample.js +71 -29
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationUrlExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/jsonResponseStreamableHttp.js +45 -6
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/jsonResponseStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleStreamableHttp.js +71 -31
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleTaskInteractive.js +61 -18
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleTaskInteractive.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js +57 -19
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/ssePollingExample.js +64 -17
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/ssePollingExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js +61 -13
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.d.ts +4 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.d.ts +17 -8
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.js +31 -14
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.d.ts +9 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.js +17 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts +12 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js +46 -2
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js +39 -9
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.d.ts +10 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js +72 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/package.json +1 -1
- package/package.json +2 -2
- package/server.js +60 -8
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ Open `http://localhost:7400`. The MCP server is at `http://localhost:7430`.
|
|
|
106
106
|
|
|
107
107
|
### Option B — npm
|
|
108
108
|
|
|
109
|
-
Requires [Node.js
|
|
109
|
+
Requires [Node.js 22+](https://nodejs.org/).
|
|
110
110
|
|
|
111
111
|
```bash
|
|
112
112
|
npm install -g @suveren/gateway
|
|
@@ -185,6 +185,40 @@ See `suveren-gateway config help` for the full command reference.
|
|
|
185
185
|
|
|
186
186
|
---
|
|
187
187
|
|
|
188
|
+
## Behind a company proxy
|
|
189
|
+
|
|
190
|
+
On a company laptop that routes all internet traffic through an HTTP(S) proxy, the gateway needs two things: the proxy address, and — if that proxy does TLS inspection — the company's root certificate.
|
|
191
|
+
|
|
192
|
+
**The proxy.** Set the standard environment variables (upper or lower case both work) before starting the gateway, or save one with the CLI:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
export HTTPS_PROXY=http://proxy.corp.example:8080
|
|
196
|
+
export HTTP_PROXY=http://proxy.corp.example:8080 # usually the same value
|
|
197
|
+
export NO_PROXY=internal.example.com # optional: hosts to reach directly
|
|
198
|
+
suveren-gateway start
|
|
199
|
+
|
|
200
|
+
# or, to save it so every future start picks it up without re-exporting:
|
|
201
|
+
suveren-gateway config set proxy http://proxy.corp.example:8080
|
|
202
|
+
suveren-gateway restart
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Every outbound call this applies to — the Authority Server, the update checker, and a remote AI assistant endpoint — honours the proxy. A loopback target (the control plane and MCP server talking to each other, or a local AI assistant such as Ollama) is **never** proxied, no matter what is set — a corporate proxy has no route back to the machine it's running on.
|
|
206
|
+
|
|
207
|
+
**TLS inspection.** Many corporate proxies intercept HTTPS by re-signing every certificate with their own root — that includes the Authority Server's. If you see a certificate error mentioning an untrusted issuer, trust the company's root the same way you would for a self-hosted Authority Server:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
suveren-gateway config set ca-file /path/to/company-root-ca.pem
|
|
211
|
+
suveren-gateway restart
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
This works through the proxy exactly like it works directly — `--ca-file` applies to the certificate the gateway actually sees, proxied or not.
|
|
215
|
+
|
|
216
|
+
**The one combination that still refuses, on purpose:** [TLS pinning](#pinning-the-authority-servers-tls-certificate) (opt-in, off by default) together with a TLS-inspecting proxy. Pinning checks the certificate the gateway sees *through* the proxy — if that's the proxy's own re-signed one rather than the real Authority Server's, the pin will not match, and the gateway refuses the connection and says so, even with the company root trusted via `--ca-file`. That refusal is correct: ask network/IT to exempt the Authority Server's host from TLS inspection, the same request you'd make for any pinned certificate on that network.
|
|
217
|
+
|
|
218
|
+
**On a company-managed machine, IT can set the proxy centrally** instead of relying on `HTTPS_PROXY` being exported in every shell — see [Managed settings](docs/managed-settings.md). A policy-set `Proxy` (Windows registry or a JSON policy file) **overrides** an already-set `HTTP_PROXY`/`HTTPS_PROXY` rather than merely filling it in, and `config set proxy` / `--proxy` refuse with "set by your IT" when it's locked. A loopback target is still never proxied, regardless.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
188
222
|
## Simulation mode — block every real system
|
|
189
223
|
|
|
190
224
|
A mandate is bound to a *profile* (e.g. "sales"), not to a specific connector. If a real
|
package/bin/suveren-gateway.js
CHANGED
|
@@ -17,9 +17,19 @@ import { homedir, platform, userInfo } from 'node:os';
|
|
|
17
17
|
import { dirname, join, resolve } from 'node:path';
|
|
18
18
|
import { fileURLToPath } from 'node:url';
|
|
19
19
|
import { buildLaunchAgentPlist, buildMacLauncher, buildSystemdUnit, buildWindowsTaskXml } from '../lib/autostart-templates.mjs';
|
|
20
|
-
import { DEFAULT_AS_URL, readConfig, writeConfig, validateAsUrl, validateCaFile, validatePinTls, resolveAsUrl, resolvePinTls, resolvePinTlsExpectedFingerprint, resolveSimulation } from '../lib/config.mjs';
|
|
20
|
+
import { DEFAULT_AS_URL, readConfig, writeConfig, validateAsUrl, validateCaFile, validateProxyUrl, validatePinTls, resolveAsUrl, resolvePinTls, resolvePinTlsExpectedFingerprint, resolveSimulation } from '../lib/config.mjs';
|
|
21
21
|
import { createInterface } from 'node:readline/promises';
|
|
22
22
|
import { readPairing as readAsPairing, recordTlsPin, formatFingerprint, normalizeFingerprint } from '../lib/as-pairing.mjs';
|
|
23
|
+
import { unsupportedNodeReason } from '../lib/node-version.mjs';
|
|
24
|
+
import { readPolicy, isPolicyLocked } from '../lib/policy.mjs';
|
|
25
|
+
|
|
26
|
+
// Before any command: on an unsupported Node the connectors cannot run (see
|
|
27
|
+
// lib/node-version.mjs), so refuse with the reason instead of starting.
|
|
28
|
+
const nodeReason = unsupportedNodeReason(process.versions.node);
|
|
29
|
+
if (nodeReason) {
|
|
30
|
+
console.error(nodeReason);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
23
33
|
|
|
24
34
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
25
35
|
const PKG_ROOT = resolve(__dirname, '..');
|
|
@@ -190,6 +200,18 @@ async function start(args) {
|
|
|
190
200
|
caFileToSave = v.path;
|
|
191
201
|
}
|
|
192
202
|
|
|
203
|
+
const proxyFlag = flagValue(args, '--proxy');
|
|
204
|
+
let proxyToSave = null;
|
|
205
|
+
if (proxyFlag) {
|
|
206
|
+
refuseIfLockedByPolicy('proxy', 'proxy');
|
|
207
|
+
const v = validateProxyUrl(proxyFlag);
|
|
208
|
+
if (!v.ok) {
|
|
209
|
+
console.error(`Invalid --proxy: ${v.error}`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
proxyToSave = v.url;
|
|
213
|
+
}
|
|
214
|
+
|
|
193
215
|
// --pin-tls: a boolean flag (turns TLS certificate pinning ON — there is
|
|
194
216
|
// no `start --pin-tls off`; use `config set pin-tls off` for that).
|
|
195
217
|
// Validated against the EFFECTIVE as-url for this very start (the flag
|
|
@@ -266,6 +288,12 @@ async function start(args) {
|
|
|
266
288
|
writeConfig(DATA_DIR, { caFile: caFileToSave });
|
|
267
289
|
console.log(`CA file: ${caFileToSave} (saved — applied to every process this gateway starts)`);
|
|
268
290
|
}
|
|
291
|
+
if (proxyToSave) {
|
|
292
|
+
writeConfig(DATA_DIR, { proxyUrl: proxyToSave });
|
|
293
|
+
process.env.HTTP_PROXY ??= proxyToSave;
|
|
294
|
+
process.env.HTTPS_PROXY ??= proxyToSave;
|
|
295
|
+
console.log(`Proxy: ${proxyToSave} (saved — applied to every process this gateway starts, unless HTTP_PROXY/HTTPS_PROXY is already set)`);
|
|
296
|
+
}
|
|
269
297
|
if (pinTlsToSave) {
|
|
270
298
|
const effectiveAsUrl = asUrlToSave ?? resolveAsUrl(DATA_DIR);
|
|
271
299
|
const committed = commitConfirmedFingerprint(DATA_DIR, effectiveAsUrl, confirmedFingerprintHex);
|
|
@@ -510,16 +538,36 @@ function printConfigHelp() {
|
|
|
510
538
|
console.log(`suveren-gateway config — read or save gateway settings
|
|
511
539
|
|
|
512
540
|
Usage:
|
|
513
|
-
suveren-gateway config get [as-url|ca-file|pin-tls] Print the resolved value(s)
|
|
541
|
+
suveren-gateway config get [as-url|ca-file|pin-tls|proxy] Print the resolved value(s)
|
|
514
542
|
suveren-gateway config set as-url <url> Save the Authority Server URL
|
|
515
543
|
suveren-gateway config set ca-file <path> Save a CA bundle for internal TLS
|
|
516
544
|
suveren-gateway config set pin-tls on --expect-fingerprint <sha256-hex>
|
|
517
545
|
Pin the Authority Server's TLS certificate
|
|
518
546
|
suveren-gateway config set pin-tls off Stop enforcing the TLS certificate pin
|
|
547
|
+
suveren-gateway config set proxy <url> Save an HTTP(S) proxy (http(s)://host:port)
|
|
519
548
|
|
|
520
549
|
Saved in ${join(DATA_DIR, 'config.json')}.
|
|
521
|
-
Precedence at start: --as-url flag > env SUVEREN_AS_URL > saved
|
|
522
|
-
default (${DEFAULT_AS_URL}).
|
|
550
|
+
Precedence at start: IT policy > --as-url flag > env SUVEREN_AS_URL > saved
|
|
551
|
+
as-url > default (${DEFAULT_AS_URL}).
|
|
552
|
+
|
|
553
|
+
A setting your organization's IT has set centrally (Windows registry policy,
|
|
554
|
+
or a policy file — see docs/managed-settings.md) is LOCKED: \`config get\`
|
|
555
|
+
shows "(set by your IT)" next to it, and \`config set\` refuses to change it.
|
|
556
|
+
|
|
557
|
+
proxy is a convenience for operators without shell access to set
|
|
558
|
+
HTTP_PROXY/HTTPS_PROXY themselves — those environment variables remain the
|
|
559
|
+
actual requirement (every process this gateway runs honours them directly)
|
|
560
|
+
and always win if already set; a saved proxy only fills in whichever of the
|
|
561
|
+
two is still unset. NO_PROXY is honoured too, read directly from the
|
|
562
|
+
environment (there is no saved equivalent). A loopback target (the control
|
|
563
|
+
plane and the MCP server talking to each other, or a local AI assistant) is
|
|
564
|
+
never proxied, independent of any of this.
|
|
565
|
+
|
|
566
|
+
An IT-set Proxy policy is the ONE locked setting that OVERRIDES an
|
|
567
|
+
already-set HTTP_PROXY/HTTPS_PROXY rather than merely out-ranking a saved
|
|
568
|
+
value — the Windows-company-laptop case, where the proxy lives in system
|
|
569
|
+
settings, not something an employee's shell exports. A NoProxy policy
|
|
570
|
+
likewise overrides NO_PROXY. See docs/managed-settings.md.
|
|
523
571
|
|
|
524
572
|
pin-tls (default off, self-hosted Authority Servers with a stable signing
|
|
525
573
|
key) requires https:// and pins the Authority Server's TLS certificate
|
|
@@ -555,21 +603,48 @@ running gateway keeps using what it already resolved at its own startup.
|
|
|
555
603
|
`);
|
|
556
604
|
}
|
|
557
605
|
|
|
606
|
+
/** Appended to `config get` output when IT policy has set this key — see
|
|
607
|
+
* lib/policy.mjs. Purely informational here; the refusal itself lives in
|
|
608
|
+
* `refuseIfLockedByPolicy`, called from `config set` / `simulation`. */
|
|
609
|
+
function policySuffix(key) {
|
|
610
|
+
return isPolicyLocked(key) ? ' (set by your IT)' : '';
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Refuse a `config set` / `simulation on|off` for a key IT policy already
|
|
615
|
+
* controls. A policy value is the top precedence tier (see policy.mjs) —
|
|
616
|
+
* writing a saved config.json value anyway would be actively misleading
|
|
617
|
+
* (`config get` would show something that is NOT what's actually running),
|
|
618
|
+
* so this exits before any validation or write happens, naming the policy
|
|
619
|
+
* value so the person doesn't have to go find it themselves.
|
|
620
|
+
*/
|
|
621
|
+
function refuseIfLockedByPolicy(key, humanName, display) {
|
|
622
|
+
if (!isPolicyLocked(key)) return;
|
|
623
|
+
const value = readPolicy().policy[key];
|
|
624
|
+
console.error(`${humanName} is set by your IT policy (${display ? display(value) : value}) and cannot be changed here.`);
|
|
625
|
+
console.error('Contact your IT administrator to change it.');
|
|
626
|
+
process.exit(1);
|
|
627
|
+
}
|
|
628
|
+
|
|
558
629
|
async function config(args) {
|
|
559
630
|
const sub = args[0];
|
|
560
631
|
|
|
561
632
|
if (sub === 'get') {
|
|
562
633
|
const key = args[1];
|
|
563
634
|
const saved = readConfig(DATA_DIR);
|
|
635
|
+
const policyCaFile = readPolicy().policy.caFile;
|
|
636
|
+
const policyProxy = readPolicy().policy.proxy;
|
|
564
637
|
if (!key) {
|
|
565
|
-
console.log(`as-url: ${resolveAsUrl(DATA_DIR)}`);
|
|
566
|
-
console.log(`ca-file: ${saved.caFile ?? '(not set)'}`);
|
|
567
|
-
console.log(`pin-tls: ${resolvePinTls(DATA_DIR) ? 'on' : 'off'}`);
|
|
638
|
+
console.log(`as-url: ${resolveAsUrl(DATA_DIR)}${policySuffix('asUrl')}`);
|
|
639
|
+
console.log(`ca-file: ${(policyCaFile ?? saved.caFile) ?? '(not set)'}${policySuffix('caFile')}`);
|
|
640
|
+
console.log(`pin-tls: ${resolvePinTls(DATA_DIR) ? 'on' : 'off'}${policySuffix('pinTls')}`);
|
|
641
|
+
console.log(`proxy: ${(policyProxy ?? saved.proxyUrl) ?? '(not set)'}${policySuffix('proxy')}`);
|
|
568
642
|
return;
|
|
569
643
|
}
|
|
570
|
-
if (key === 'as-url') { console.log(resolveAsUrl(DATA_DIR)); return; }
|
|
571
|
-
if (key === 'ca-file') { console.log(saved.caFile ?? ''); return; }
|
|
572
|
-
if (key === 'pin-tls') { console.log(resolvePinTls(DATA_DIR) ? 'on' : 'off'); return; }
|
|
644
|
+
if (key === 'as-url') { console.log(`${resolveAsUrl(DATA_DIR)}${policySuffix('asUrl')}`); return; }
|
|
645
|
+
if (key === 'ca-file') { console.log(`${(policyCaFile ?? saved.caFile) ?? ''}${policySuffix('caFile')}`); return; }
|
|
646
|
+
if (key === 'pin-tls') { console.log(`${resolvePinTls(DATA_DIR) ? 'on' : 'off'}${policySuffix('pinTls')}`); return; }
|
|
647
|
+
if (key === 'proxy') { console.log(`${(policyProxy ?? saved.proxyUrl) ?? ''}${policySuffix('proxy')}`); return; }
|
|
573
648
|
console.error(`Unknown config key: ${key}\n`);
|
|
574
649
|
printConfigHelp();
|
|
575
650
|
process.exit(2);
|
|
@@ -579,6 +654,7 @@ async function config(args) {
|
|
|
579
654
|
const key = args[1];
|
|
580
655
|
const value = args[2];
|
|
581
656
|
if (key === 'as-url') {
|
|
657
|
+
refuseIfLockedByPolicy('asUrl', 'as-url');
|
|
582
658
|
if (!value) {
|
|
583
659
|
console.error('Usage: suveren-gateway config set as-url <url>');
|
|
584
660
|
process.exit(2);
|
|
@@ -594,6 +670,7 @@ async function config(args) {
|
|
|
594
670
|
return;
|
|
595
671
|
}
|
|
596
672
|
if (key === 'ca-file') {
|
|
673
|
+
refuseIfLockedByPolicy('caFile', 'ca-file');
|
|
597
674
|
if (!value) {
|
|
598
675
|
console.error('Usage: suveren-gateway config set ca-file <path>');
|
|
599
676
|
process.exit(2);
|
|
@@ -608,7 +685,25 @@ async function config(args) {
|
|
|
608
685
|
console.log('Restart to pick it up: suveren-gateway restart');
|
|
609
686
|
return;
|
|
610
687
|
}
|
|
688
|
+
if (key === 'proxy') {
|
|
689
|
+
refuseIfLockedByPolicy('proxy', 'proxy');
|
|
690
|
+
if (!value) {
|
|
691
|
+
console.error('Usage: suveren-gateway config set proxy <url>');
|
|
692
|
+
process.exit(2);
|
|
693
|
+
}
|
|
694
|
+
const v = validateProxyUrl(value);
|
|
695
|
+
if (!v.ok) {
|
|
696
|
+
console.error(`Invalid proxy: ${v.error}`);
|
|
697
|
+
process.exit(1);
|
|
698
|
+
}
|
|
699
|
+
writeConfig(DATA_DIR, { proxyUrl: v.url });
|
|
700
|
+
console.log(`Saved proxy: ${v.url}`);
|
|
701
|
+
console.log('Sets HTTP_PROXY/HTTPS_PROXY for every process this gateway starts, unless already set in the environment.');
|
|
702
|
+
console.log('Restart to pick it up: suveren-gateway restart');
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
611
705
|
if (key === 'pin-tls') {
|
|
706
|
+
refuseIfLockedByPolicy('pinTls', 'pin-tls', (v) => (v ? 'on' : 'off'));
|
|
612
707
|
if (value !== 'on' && value !== 'off') {
|
|
613
708
|
console.error('Usage: suveren-gateway config set pin-tls on|off [--expect-fingerprint <sha256-hex>]');
|
|
614
709
|
process.exit(2);
|
|
@@ -670,12 +765,17 @@ Usage:
|
|
|
670
765
|
suveren-gateway simulation status Show the saved setting and (if running) the live one
|
|
671
766
|
|
|
672
767
|
Changes take effect on the next \`suveren-gateway start\` / \`restart\`.
|
|
768
|
+
|
|
769
|
+
If your organization's IT has set Simulation centrally (Windows registry
|
|
770
|
+
policy, or a policy file — see docs/managed-settings.md), it is LOCKED: both
|
|
771
|
+
\`on\` and \`off\` refuse, naming the policy value, and this cannot be
|
|
772
|
+
overridden locally — not even by setting SUVEREN_SIMULATION directly.
|
|
673
773
|
`);
|
|
674
774
|
}
|
|
675
775
|
|
|
676
776
|
async function printSimulationStatus() {
|
|
677
777
|
const saved = resolveSimulation(DATA_DIR);
|
|
678
|
-
console.log(`Saved: ${saved ? 'on' : 'off'}`);
|
|
778
|
+
console.log(`Saved: ${saved ? 'on' : 'off'}${policySuffix('simulation')}`);
|
|
679
779
|
try {
|
|
680
780
|
const res = await fetch(`http://localhost:${SUVEREN_PORT}/health`, { signal: AbortSignal.timeout(3000) });
|
|
681
781
|
if (res.ok) {
|
|
@@ -711,6 +811,7 @@ async function simulation(args) {
|
|
|
711
811
|
}
|
|
712
812
|
|
|
713
813
|
if (sub === 'on') {
|
|
814
|
+
refuseIfLockedByPolicy('simulation', 'Simulation mode', (v) => (v ? 'on' : 'off'));
|
|
714
815
|
// The safe direction — blocking real systems needs no confirmation.
|
|
715
816
|
writeConfig(DATA_DIR, { simulation: true });
|
|
716
817
|
console.log('Simulation mode: ON (saved) — every connector without a manifest "simulation" marker will be blocked.');
|
|
@@ -719,6 +820,7 @@ async function simulation(args) {
|
|
|
719
820
|
}
|
|
720
821
|
|
|
721
822
|
if (sub === 'off') {
|
|
823
|
+
refuseIfLockedByPolicy('simulation', 'Simulation mode', (v) => (v ? 'on' : 'off'));
|
|
722
824
|
console.error('Turning simulation mode OFF makes every real system reachable again: any connector');
|
|
723
825
|
console.error('without a manifest "simulation" marker (e.g. a live Gmail or ERP account) will spawn');
|
|
724
826
|
console.error('and execute for real the next time this gateway starts.');
|
|
@@ -986,6 +1088,19 @@ async function serviceInstallWindows() {
|
|
|
986
1088
|
// Deliberately does NOT stop the running gateway — see the macOS note.
|
|
987
1089
|
// Registering is enough; Task Scheduler starts it at the next logon.
|
|
988
1090
|
|
|
1091
|
+
// SUVEREN_LAUNCHER (set by the Windows installer's launcher.cmd, never by
|
|
1092
|
+
// a plain npm/dev install) means this `service install` was itself invoked
|
|
1093
|
+
// THROUGH that launcher — route the scheduled task through it too, instead
|
|
1094
|
+
// of straight at node.exe/server.js. The launcher sets SUVEREN_INSTALL_
|
|
1095
|
+
// METHOD/SUVEREN_OFFLINE/SUVEREN_INTEGRATIONS_DIR/PATH itself, scoped to
|
|
1096
|
+
// just the gateway process it starts; writing those into HKCU\Environment
|
|
1097
|
+
// (an earlier version of the installer did this) is ACCOUNT-WIDE — it
|
|
1098
|
+
// would shadow a developer's own Node for every other program on that
|
|
1099
|
+
// account and force every other gateway install under the same user into
|
|
1100
|
+
// offline+managed mode too. Absent (every non-managed install), this is a
|
|
1101
|
+
// no-op: buildWindowsTaskXml renders identically to before.
|
|
1102
|
+
const launcherPath = process.env.SUVEREN_LAUNCHER;
|
|
1103
|
+
|
|
989
1104
|
// schtasks reads the XML from a file and requires UTF-16 LE with a BOM —
|
|
990
1105
|
// it rejects UTF-8 with an unhelpful "The task XML is malformed".
|
|
991
1106
|
const xml = buildWindowsTaskXml({
|
|
@@ -994,6 +1109,7 @@ async function serviceInstallWindows() {
|
|
|
994
1109
|
author: 'Suveren',
|
|
995
1110
|
dataDir: process.env.SUVEREN_DATA_DIR ?? '',
|
|
996
1111
|
userId: windowsUserId(),
|
|
1112
|
+
...(launcherPath ? { command: launcherPath, args: 'run' } : {}),
|
|
997
1113
|
});
|
|
998
1114
|
const xmlPath = join(DATA_DIR, 'suveren-task.xml');
|
|
999
1115
|
writeFileSync(xmlPath, '\ufeff' + xml, { encoding: 'utf16le' });
|
|
@@ -1248,6 +1364,7 @@ Usage:
|
|
|
1248
1364
|
suveren-gateway start [--detach] Run the gateway (foreground by default)
|
|
1249
1365
|
[--as-url <url>] Authority Server URL (saved for next time)
|
|
1250
1366
|
[--ca-file <path>] Internal CA bundle (saved for next time)
|
|
1367
|
+
[--proxy <url>] HTTP(S) proxy (saved for next time — see below)
|
|
1251
1368
|
[--pin-tls --expect-fingerprint <hex>] Pin the AS TLS certificate (saved; https:// only — see below)
|
|
1252
1369
|
[--simulation] Block every real system (saved — see \`simulation help\`)
|
|
1253
1370
|
suveren-gateway stop Stop a detached gateway
|
|
@@ -1256,9 +1373,10 @@ Usage:
|
|
|
1256
1373
|
suveren-gateway logs [--tail] Print or tail ~/.suveren/gateway.log
|
|
1257
1374
|
suveren-gateway service <cmd> Run as a login service that survives reboot
|
|
1258
1375
|
(install | uninstall | status)
|
|
1259
|
-
suveren-gateway config get [as-url|ca-file|pin-tls] Print the resolved value(s)
|
|
1376
|
+
suveren-gateway config get [as-url|ca-file|pin-tls|proxy] Print the resolved value(s)
|
|
1260
1377
|
suveren-gateway config set as-url <url> Save the Authority Server URL
|
|
1261
1378
|
suveren-gateway config set ca-file <path> Save a CA bundle for internal TLS
|
|
1379
|
+
suveren-gateway config set proxy <url> Save an HTTP(S) proxy (see below)
|
|
1262
1380
|
suveren-gateway config set pin-tls on --expect-fingerprint <hex>
|
|
1263
1381
|
Pin the Authority Server's TLS certificate
|
|
1264
1382
|
(see \`suveren-gateway config help\` for the fingerprint check)
|
|
@@ -1273,6 +1391,13 @@ Environment:
|
|
|
1273
1391
|
SUVEREN_DATA_DIR Data directory (default ~/.suveren)
|
|
1274
1392
|
SUVEREN_AS_URL Authority Server URL — overrides the saved as-url
|
|
1275
1393
|
SUVEREN_SIMULATION 1 to force simulation mode for this run — overrides the saved setting
|
|
1394
|
+
HTTP_PROXY / HTTPS_PROXY / NO_PROXY (upper or lower case)
|
|
1395
|
+
Corporate proxy — honoured for every outbound call to the Authority
|
|
1396
|
+
Server, the update checker, and a remote AI assistant endpoint. A
|
|
1397
|
+
loopback target (127.0.0.1/localhost, incl. a local AI assistant) is
|
|
1398
|
+
never proxied. These win over a saved \`config set proxy\` — UNLESS
|
|
1399
|
+
your organization's IT has set a Proxy/NoProxy policy, which wins
|
|
1400
|
+
over both (see docs/managed-settings.md).
|
|
1276
1401
|
|
|
1277
1402
|
Authority Server resolution order: --as-url flag > SUVEREN_AS_URL env >
|
|
1278
1403
|
saved as-url (\`config set as-url\`) > default (${DEFAULT_AS_URL}).
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"icon": "users",
|
|
7
7
|
"profile": "customers",
|
|
8
8
|
"npmPackage": "@humanagencyp/crm-mcp",
|
|
9
|
+
"npmVersion": "1.1.2",
|
|
9
10
|
"mcp": {
|
|
10
11
|
"command": "crm-mcp",
|
|
11
12
|
"args": []
|
|
@@ -142,73 +143,6 @@
|
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
145
|
},
|
|
145
|
-
"templates": [
|
|
146
|
-
{
|
|
147
|
-
"name": "Browse & Log",
|
|
148
|
-
"description": "Search contacts, view pipeline and timeline, log activities. No creates or deletes.",
|
|
149
|
-
"risk": "low",
|
|
150
|
-
"mode": "automatic",
|
|
151
|
-
"bounds": {
|
|
152
|
-
"read_access": "unlimited",
|
|
153
|
-
"write_daily_max": "50",
|
|
154
|
-
"delete_daily_max": "0",
|
|
155
|
-
"setup_daily_max": "0"
|
|
156
|
-
},
|
|
157
|
-
"context": {
|
|
158
|
-
"contact_type": "customer,lead,partner,vendor"
|
|
159
|
-
},
|
|
160
|
-
"intent": "Allow the agent to browse CRM data and log activities. Read and log only — no creating, editing, or deleting records.",
|
|
161
|
-
"ttl": 2592000,
|
|
162
|
-
"tags": [
|
|
163
|
-
"read + log",
|
|
164
|
-
"no deletes"
|
|
165
|
-
]
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
"name": "Full CRM with Review",
|
|
169
|
-
"description": "Create contacts, deals, and tasks. Update and delete records. Every write requires approval.",
|
|
170
|
-
"risk": "high",
|
|
171
|
-
"mode": "review",
|
|
172
|
-
"bounds": {
|
|
173
|
-
"read_access": "unlimited",
|
|
174
|
-
"write_daily_max": "50",
|
|
175
|
-
"delete_daily_max": "10",
|
|
176
|
-
"setup_daily_max": "0"
|
|
177
|
-
},
|
|
178
|
-
"context": {
|
|
179
|
-
"contact_type": "customer,lead,partner,vendor"
|
|
180
|
-
},
|
|
181
|
-
"intent": "Full CRM management — create, update, and delete contacts, deals, and tasks. Every write action requires my review before execution.",
|
|
182
|
-
"ttl": 2592000,
|
|
183
|
-
"tags": [
|
|
184
|
-
"50 writes/day",
|
|
185
|
-
"10 deletes/day",
|
|
186
|
-
"review mode"
|
|
187
|
-
]
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
"name": "Load test data (with approval)",
|
|
191
|
-
"description": "Load a simulation package (customers and optional contacts) into the simulated CRM, for setting up a three-week test. No browsing, writing, or deleting — this template grants nothing but the one-time test-data load, and it still requires your approval.",
|
|
192
|
-
"risk": "high",
|
|
193
|
-
"mode": "review",
|
|
194
|
-
"bounds": {
|
|
195
|
-
"read_access": "none",
|
|
196
|
-
"write_daily_max": "0",
|
|
197
|
-
"delete_daily_max": "0",
|
|
198
|
-
"setup_daily_max": "1"
|
|
199
|
-
},
|
|
200
|
-
"context": {
|
|
201
|
-
"contact_type": "customer"
|
|
202
|
-
},
|
|
203
|
-
"intent": "Allow the agent to load one simulation package of test data into the simulated CRM, for my review before it happens. No other CRM action is granted by this mandate — set up test data separately from the mandate the agent uses for its actual work.",
|
|
204
|
-
"ttl": 2592000,
|
|
205
|
-
"tags": [
|
|
206
|
-
"setup only",
|
|
207
|
-
"review mode",
|
|
208
|
-
"1 load"
|
|
209
|
-
]
|
|
210
|
-
}
|
|
211
|
-
],
|
|
212
146
|
"setupHint": "No configuration needed — works out of the box.",
|
|
213
147
|
"setupGuide": [
|
|
214
148
|
{
|
|
@@ -6,12 +6,10 @@
|
|
|
6
6
|
"icon": "wrench",
|
|
7
7
|
"profile": "deploy",
|
|
8
8
|
"npmPackage": "@humanagencyp/deploy-mcp",
|
|
9
|
+
"npmVersion": "0.4.2",
|
|
9
10
|
"mcp": {
|
|
10
|
-
"command": "
|
|
11
|
-
"args": [
|
|
12
|
-
"-y",
|
|
13
|
-
"@humanagencyp/deploy-mcp@latest"
|
|
14
|
-
]
|
|
11
|
+
"command": "deploy-mcp",
|
|
12
|
+
"args": []
|
|
15
13
|
},
|
|
16
14
|
"credentials": {
|
|
17
15
|
"fields": [
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"icon": "briefcase",
|
|
7
7
|
"profile": "sales",
|
|
8
8
|
"npmPackage": "@humanagencyp/erp-mcp",
|
|
9
|
+
"npmVersion": "0.3.3",
|
|
9
10
|
"mcp": {
|
|
10
11
|
"command": "erp-mcp",
|
|
11
12
|
"args": []
|
|
@@ -138,86 +139,6 @@
|
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
},
|
|
141
|
-
"templates": [
|
|
142
|
-
{
|
|
143
|
-
"name": "Draft quotes",
|
|
144
|
-
"description": "Look up items and customers, create and edit draft quotes. Nothing is sent to a customer or converted to an order.",
|
|
145
|
-
"risk": "low",
|
|
146
|
-
"mode": "automatic",
|
|
147
|
-
"bounds": {
|
|
148
|
-
"read_access": "unlimited",
|
|
149
|
-
"value_max": "5000",
|
|
150
|
-
"discount_max": "15",
|
|
151
|
-
"order_value_daily_max": "0",
|
|
152
|
-
"quote_daily_max": "20",
|
|
153
|
-
"send_daily_max": "0",
|
|
154
|
-
"order_daily_max": "0",
|
|
155
|
-
"setup_daily_max": "0"
|
|
156
|
-
},
|
|
157
|
-
"context": {
|
|
158
|
-
"currency": "EUR"
|
|
159
|
-
},
|
|
160
|
-
"intent": "Allow the agent to browse items and customers and prepare draft quotes for my review. It cannot send a quote to a customer or convert one into an order.",
|
|
161
|
-
"ttl": 2592000,
|
|
162
|
-
"tags": [
|
|
163
|
-
"drafts only",
|
|
164
|
-
"no sends",
|
|
165
|
-
"no orders"
|
|
166
|
-
]
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
"name": "Send and confirm with review above limit",
|
|
170
|
-
"description": "Draft, send, and convert quotes into orders. Every send and every order requires your approval.",
|
|
171
|
-
"risk": "high",
|
|
172
|
-
"mode": "review",
|
|
173
|
-
"bounds": {
|
|
174
|
-
"read_access": "unlimited",
|
|
175
|
-
"value_max": "20000",
|
|
176
|
-
"discount_max": "20",
|
|
177
|
-
"order_value_daily_max": "50000",
|
|
178
|
-
"quote_daily_max": "50",
|
|
179
|
-
"send_daily_max": "20",
|
|
180
|
-
"order_daily_max": "10",
|
|
181
|
-
"setup_daily_max": "0"
|
|
182
|
-
},
|
|
183
|
-
"context": {
|
|
184
|
-
"currency": "EUR"
|
|
185
|
-
},
|
|
186
|
-
"intent": "Allow the agent to draft, send, and convert quotes into orders. Every quote sent to a customer and every order requires my review before it happens.",
|
|
187
|
-
"ttl": 2592000,
|
|
188
|
-
"tags": [
|
|
189
|
-
"20k EUR/document",
|
|
190
|
-
"review mode",
|
|
191
|
-
"10 orders/day"
|
|
192
|
-
]
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
"name": "Load test data (with approval)",
|
|
196
|
-
"description": "Load a simulation package (customers and products) into the simulated ERP, for setting up a three-week test. No quoting, sending, or ordering — this template grants nothing but the one-time test-data load, and it still requires your approval.",
|
|
197
|
-
"risk": "high",
|
|
198
|
-
"mode": "review",
|
|
199
|
-
"bounds": {
|
|
200
|
-
"read_access": "none",
|
|
201
|
-
"value_max": "0",
|
|
202
|
-
"discount_max": "0",
|
|
203
|
-
"order_value_daily_max": "0",
|
|
204
|
-
"quote_daily_max": "0",
|
|
205
|
-
"send_daily_max": "0",
|
|
206
|
-
"order_daily_max": "0",
|
|
207
|
-
"setup_daily_max": "1"
|
|
208
|
-
},
|
|
209
|
-
"context": {
|
|
210
|
-
"currency": "EUR"
|
|
211
|
-
},
|
|
212
|
-
"intent": "Allow the agent to load one simulation package of test data into the simulated ERP, for my review before it happens. No other ERP action is granted by this mandate — set up test data separately from the mandate the agent uses for its actual work.",
|
|
213
|
-
"ttl": 2592000,
|
|
214
|
-
"tags": [
|
|
215
|
-
"setup only",
|
|
216
|
-
"review mode",
|
|
217
|
-
"1 load"
|
|
218
|
-
]
|
|
219
|
-
}
|
|
220
|
-
],
|
|
221
142
|
"setupHint": "No configuration needed — works out of the box.",
|
|
222
143
|
"setupGuide": [
|
|
223
144
|
{
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"icon": "mail",
|
|
7
7
|
"profile": "email",
|
|
8
8
|
"npmPackage": "@humanagencyp/email-mcp",
|
|
9
|
+
"npmVersion": "0.1.3",
|
|
9
10
|
"mcp": {
|
|
10
11
|
"command": "email-mcp",
|
|
11
12
|
"args": []
|
|
@@ -86,54 +87,6 @@
|
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
},
|
|
89
|
-
"templates": [
|
|
90
|
-
{
|
|
91
|
-
"name": "Work the inbox",
|
|
92
|
-
"description": "Read the simulated inbox and send replies. Cannot load or replace test data.",
|
|
93
|
-
"risk": "low",
|
|
94
|
-
"mode": "automatic",
|
|
95
|
-
"bounds": {
|
|
96
|
-
"read_access": "unlimited",
|
|
97
|
-
"recipient_max": "1",
|
|
98
|
-
"send_daily_max": "50",
|
|
99
|
-
"setup_daily_max": "0"
|
|
100
|
-
},
|
|
101
|
-
"context": {
|
|
102
|
-
"allowed_recipients": "",
|
|
103
|
-
"allowed_domains": ""
|
|
104
|
-
},
|
|
105
|
-
"intent": "Allow the agent to read the simulated inbox and reply to messages on its own. It cannot load or replace the test data the inbox was seeded with.",
|
|
106
|
-
"ttl": 2592000,
|
|
107
|
-
"tags": [
|
|
108
|
-
"read + reply",
|
|
109
|
-
"automatic",
|
|
110
|
-
"no setup"
|
|
111
|
-
]
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
"name": "Load test data (with approval)",
|
|
115
|
-
"description": "Load a simulation package into an empty inbox. No reading or sending — a separate, one-time setup mandate.",
|
|
116
|
-
"risk": "high",
|
|
117
|
-
"mode": "review",
|
|
118
|
-
"bounds": {
|
|
119
|
-
"read_access": "none",
|
|
120
|
-
"recipient_max": "0",
|
|
121
|
-
"send_daily_max": "0",
|
|
122
|
-
"setup_daily_max": "1"
|
|
123
|
-
},
|
|
124
|
-
"context": {
|
|
125
|
-
"allowed_recipients": "",
|
|
126
|
-
"allowed_domains": ""
|
|
127
|
-
},
|
|
128
|
-
"intent": "Allow the agent to load one simulation package into an empty inbox, with my review before it happens. No reading or sending under this mandate — grant it separately from the mandate the agent uses for its daily work.",
|
|
129
|
-
"ttl": 2592000,
|
|
130
|
-
"tags": [
|
|
131
|
-
"setup only",
|
|
132
|
-
"review mode",
|
|
133
|
-
"1 load/day"
|
|
134
|
-
]
|
|
135
|
-
}
|
|
136
|
-
],
|
|
137
90
|
"setupHint": "No configuration needed — works out of the box, in simulation mode.",
|
|
138
91
|
"setupGuide": [
|
|
139
92
|
{
|