@suveren/gateway 0.4.1 → 0.6.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/bin/suveren-gateway.js +86 -5
- package/content/integrations/calendar.json +116 -22
- package/content/integrations/deploy-github.json +164 -0
- package/content/integrations/gmail.json +13 -4
- package/content/integrations/index.json +2 -1
- package/dist/control-plane/index.mjs +84 -7
- package/dist/mcp-server/http.mjs +147 -21
- package/dist/ui/assets/index-DecSrutK.js +105 -0
- package/dist/ui/index.html +1 -1
- package/node_modules/@hap/core/dist/index.d.mts +21 -0
- package/node_modules/@hap/core/dist/index.d.ts +21 -0
- package/node_modules/@hap/core/dist/index.js +17 -0
- package/node_modules/@hap/core/dist/index.mjs +17 -0
- package/node_modules/@hap/core/package.json +1 -1
- package/node_modules/@hap/core/src/gatekeeper.ts +28 -0
- package/node_modules/@hap/core/src/types.ts +21 -0
- package/node_modules/fast-uri/index.js +37 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +136 -0
- package/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/cjs/jsx/base.js +1 -9
- package/node_modules/hono/dist/cjs/jsx/hooks/index.js +14 -11
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/cjs/utils/cookie.js +2 -1
- package/node_modules/hono/dist/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/jsx/base.js +1 -9
- package/node_modules/hono/dist/jsx/hooks/index.js +14 -11
- package/node_modules/hono/dist/middleware/cors/index.js +1 -1
- package/node_modules/hono/dist/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/utils/cookie.js +2 -1
- package/node_modules/hono/package.json +2 -3
- package/node_modules/ip-address/README.md +142 -128
- package/node_modules/ip-address/dist/common.d.ts +6 -0
- package/node_modules/ip-address/dist/common.js +17 -1
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.js +3 -12
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +9 -2
- package/node_modules/ip-address/dist/ipv6.js +35 -16
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/package.json +5 -3
- package/node_modules/jose/README.md +13 -13
- package/node_modules/jose/dist/types/index.d.ts +6 -5
- package/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts +17 -11
- package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +7 -19
- package/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts +17 -11
- package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +7 -19
- package/node_modules/jose/dist/types/jwe/general/decrypt.d.ts +18 -13
- package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +20 -21
- package/node_modules/jose/dist/types/jwk/embedded.d.ts +8 -12
- package/node_modules/jose/dist/types/jwk/thumbprint.d.ts +0 -15
- package/node_modules/jose/dist/types/jwks/local.d.ts +12 -21
- package/node_modules/jose/dist/types/jwks/remote.d.ts +34 -165
- package/node_modules/jose/dist/types/jws/compact/sign.d.ts +2 -13
- package/node_modules/jose/dist/types/jws/compact/verify.d.ts +17 -13
- package/node_modules/jose/dist/types/jws/flattened/sign.d.ts +2 -13
- package/node_modules/jose/dist/types/jws/flattened/verify.d.ts +17 -13
- package/node_modules/jose/dist/types/jws/general/sign.d.ts +16 -17
- package/node_modules/jose/dist/types/jws/general/verify.d.ts +18 -15
- package/node_modules/jose/dist/types/jwt/decrypt.d.ts +17 -11
- package/node_modules/jose/dist/types/jwt/encrypt.d.ts +10 -34
- package/node_modules/jose/dist/types/jwt/sign.d.ts +2 -13
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +4 -13
- package/node_modules/jose/dist/types/jwt/verify.d.ts +14 -13
- package/node_modules/jose/dist/types/key/export.d.ts +0 -14
- package/node_modules/jose/dist/types/key/generate_key_pair.d.ts +7 -14
- package/node_modules/jose/dist/types/key/generate_secret.d.ts +16 -14
- package/node_modules/jose/dist/types/key/import.d.ts +18 -28
- package/node_modules/jose/dist/types/types.d.ts +239 -222
- package/node_modules/jose/dist/types/util/base64url.d.ts +11 -4
- package/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -9
- package/node_modules/jose/dist/types/util/decode_protected_header.d.ts +0 -8
- package/node_modules/jose/dist/types/util/errors.d.ts +128 -121
- package/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +4 -22
- package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +5 -153
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +16 -111
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +15 -3
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +65 -81
- package/node_modules/jose/dist/webapi/jwk/embedded.js +5 -3
- package/node_modules/jose/dist/webapi/jwks/local.js +31 -72
- package/node_modules/jose/dist/webapi/jwks/remote.js +19 -28
- package/node_modules/jose/dist/webapi/jws/compact/sign.js +5 -2
- package/node_modules/jose/dist/webapi/jws/compact/verify.js +4 -16
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +7 -65
- package/node_modules/jose/dist/webapi/jws/flattened/verify.js +3 -89
- package/node_modules/jose/dist/webapi/jws/general/sign.js +19 -15
- package/node_modules/jose/dist/webapi/jws/general/verify.js +29 -9
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +5 -5
- package/node_modules/jose/dist/webapi/jwt/sign.js +2 -3
- package/node_modules/jose/dist/webapi/jwt/unsecured.js +4 -3
- package/node_modules/jose/dist/webapi/jwt/verify.js +6 -6
- package/node_modules/jose/dist/webapi/key/export.js +37 -4
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +33 -82
- package/node_modules/jose/dist/webapi/key/import.js +8 -8
- package/node_modules/jose/dist/webapi/lib/asn1.js +53 -122
- package/node_modules/jose/dist/webapi/lib/buffer_utils.js +1 -0
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +34 -109
- package/node_modules/jose/dist/webapi/lib/crypto_key.js +18 -126
- package/node_modules/jose/dist/webapi/lib/helpers.js +23 -0
- package/node_modules/jose/dist/webapi/lib/invalid_key_input.js +0 -1
- package/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +116 -0
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +186 -0
- package/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +110 -0
- package/node_modules/jose/dist/webapi/lib/jwk_to_key.js +8 -98
- package/node_modules/jose/dist/webapi/lib/jws_algorithms.js +76 -0
- package/node_modules/jose/dist/webapi/lib/jws_sign.js +74 -0
- package/node_modules/jose/dist/webapi/lib/jws_verify.js +107 -0
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +68 -109
- package/node_modules/jose/dist/webapi/lib/key.js +132 -0
- package/node_modules/jose/dist/webapi/lib/key_algorithm.js +10 -0
- package/node_modules/jose/dist/webapi/lib/key_descriptor.js +7 -0
- package/node_modules/jose/dist/webapi/lib/key_management.js +162 -92
- package/node_modules/jose/dist/webapi/lib/options.js +48 -0
- package/node_modules/jose/dist/webapi/lib/signing.js +14 -56
- package/node_modules/jose/dist/webapi/lib/type_checks.js +13 -18
- package/node_modules/jose/dist/webapi/util/base64url.js +13 -4
- package/node_modules/jose/dist/webapi/util/decode_jwt.js +2 -2
- package/node_modules/jose/dist/webapi/util/decode_protected_header.js +5 -15
- package/node_modules/jose/dist/webapi/util/errors.js +1 -1
- package/node_modules/jose/package.json +2 -4
- package/package.json +2 -2
- package/profiles/deploy/0.6.profile.json +168 -0
- package/profiles/deploy/0.7.profile.json +168 -0
- package/profiles/email/0.4.profile.json +9 -2
- package/profiles/index.json +3 -1
- package/dist/ui/assets/index-Cog54HOo.js +0 -105
- package/node_modules/jose/dist/webapi/lib/aesgcmkw.js +0 -15
- package/node_modules/jose/dist/webapi/lib/aeskw.js +0 -25
- package/node_modules/jose/dist/webapi/lib/check_key_type.js +0 -122
- package/node_modules/jose/dist/webapi/lib/ecdhes.js +0 -52
- package/node_modules/jose/dist/webapi/lib/key_to_jwk.js +0 -34
- package/node_modules/jose/dist/webapi/lib/normalize_key.js +0 -166
- package/node_modules/jose/dist/webapi/lib/pbes2kw.js +0 -42
- package/node_modules/jose/dist/webapi/lib/rsaes.js +0 -24
- package/node_modules/jose/dist/webapi/lib/validate_algorithms.js +0 -10
- package/node_modules/jose/dist/webapi/lib/validate_crit.js +0 -33
package/bin/suveren-gateway.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { spawn, spawnSync } from 'node:child_process';
|
|
14
|
+
import { createConnection } from 'node:net';
|
|
14
15
|
import { existsSync, mkdirSync, openSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'node:fs';
|
|
15
16
|
import { homedir, platform } from 'node:os';
|
|
16
17
|
import { dirname, join, resolve } from 'node:path';
|
|
@@ -60,6 +61,24 @@ async function start(args) {
|
|
|
60
61
|
process.exit(1);
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
// The PID file only knows about instances THIS CLI started. A gateway
|
|
65
|
+
// started by the login service — or from another shell — leaves none, so the
|
|
66
|
+
// check above passes, we spawn, the child dies instantly with EADDRINUSE,
|
|
67
|
+
// and its error goes only to the log. The user gets "started (pid N)" for a
|
|
68
|
+
// process that is already dead. Ask the port, not just the file.
|
|
69
|
+
if (await isPortListening(SUVEREN_PORT)) {
|
|
70
|
+
console.error(`Port ${SUVEREN_PORT} is already in use.`);
|
|
71
|
+
console.error(``);
|
|
72
|
+
console.error(`Something is already serving there — most likely a gateway started by the`);
|
|
73
|
+
console.error(`login service or from another terminal, which leaves no PID file for this`);
|
|
74
|
+
console.error(`CLI to find.`);
|
|
75
|
+
console.error(``);
|
|
76
|
+
console.error(` Check what it is: suveren-gateway status`);
|
|
77
|
+
console.error(` Stop a login service: suveren-gateway service uninstall`);
|
|
78
|
+
console.error(` Or use another port: SUVEREN_CP_PORT=3410 suveren-gateway start`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
63
82
|
ensureDataDir();
|
|
64
83
|
|
|
65
84
|
if (detach) {
|
|
@@ -71,6 +90,24 @@ async function start(args) {
|
|
|
71
90
|
});
|
|
72
91
|
writeFileSync(PID_FILE, String(child.pid), 'utf8');
|
|
73
92
|
child.unref();
|
|
93
|
+
|
|
94
|
+
// "started" must mean SERVING. A detached child that dies on startup takes
|
|
95
|
+
// its error to the log, so reporting success on spawn alone hands the user
|
|
96
|
+
// a pid that no longer exists and a browser tab that will not connect.
|
|
97
|
+
const serving = await waitForListening(SUVEREN_PORT, 20_000);
|
|
98
|
+
if (!serving) {
|
|
99
|
+
safeUnlink(PID_FILE);
|
|
100
|
+
console.error(`suveren-gateway failed to start — nothing is listening on ${SUVEREN_PORT}.`);
|
|
101
|
+
console.error(``);
|
|
102
|
+
console.error(` Log: ${LOG_FILE}`);
|
|
103
|
+
console.error(` Last lines:`);
|
|
104
|
+
try {
|
|
105
|
+
const tail = readFileSync(LOG_FILE, 'utf8').trimEnd().split('\n').slice(-8);
|
|
106
|
+
for (const line of tail) console.error(` ${line}`);
|
|
107
|
+
} catch { /* no log yet */ }
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
74
111
|
console.log(`suveren-gateway started (pid ${child.pid})`);
|
|
75
112
|
console.log(``);
|
|
76
113
|
console.log(` → Open in your browser: http://localhost:${SUVEREN_PORT}`);
|
|
@@ -313,14 +350,30 @@ async function serviceInstallMac() {
|
|
|
313
350
|
|
|
314
351
|
const uid = process.getuid();
|
|
315
352
|
// Clear any prior "disabled" mark from a previous uninstall, so the agent is
|
|
316
|
-
// eligible again
|
|
317
|
-
// gateway alongside the running one and fight over the port.
|
|
353
|
+
// eligible again.
|
|
318
354
|
runQuiet('launchctl', ['enable', `gui/${uid}/${LAUNCH_AGENT_LABEL}`]);
|
|
319
355
|
|
|
356
|
+
// Bootstrap NOW only when nothing is already serving. With a gateway running,
|
|
357
|
+
// loading the agent starts a second one that loses the port race and then
|
|
358
|
+
// crash-loops under KeepAlive — so in that case the agent waits for the next
|
|
359
|
+
// login, when the manual instance is gone. With nothing running there is no
|
|
360
|
+
// conflict, and waiting would leave the user with a "service" that isn't
|
|
361
|
+
// running and no obvious reason why.
|
|
362
|
+
const running = await isAlreadyRunning();
|
|
363
|
+
let loadedNow = false;
|
|
364
|
+
if (!running) {
|
|
365
|
+
const r = runQuiet('launchctl', ['bootstrap', `gui/${uid}`, plistPath]);
|
|
366
|
+
loadedNow = r.status === 0;
|
|
367
|
+
}
|
|
368
|
+
|
|
320
369
|
console.log(`✓ Suveren gateway installed as a login service.`);
|
|
321
370
|
console.log(``);
|
|
322
|
-
|
|
323
|
-
|
|
371
|
+
if (loadedNow) {
|
|
372
|
+
console.log(` It is running now, starts automatically at login, and restarts if it crashes.`);
|
|
373
|
+
} else {
|
|
374
|
+
console.log(` It starts automatically from your NEXT login, and restarts if it crashes.`);
|
|
375
|
+
if (running) console.log(` Your current gateway keeps running — nothing was interrupted.`);
|
|
376
|
+
}
|
|
324
377
|
console.log(` After a reboot it comes up LOCKED — open http://localhost:${SUVEREN_PORT} and`);
|
|
325
378
|
console.log(` enter your Suveren API key once to unlock it (your key is never stored).`);
|
|
326
379
|
console.log(``);
|
|
@@ -358,7 +411,13 @@ async function serviceStatusMac() {
|
|
|
358
411
|
const state = /state = (\w+)/.exec(p.stdout || '');
|
|
359
412
|
console.log(` launchd: loaded${state ? ` (${state[1]})` : ''}`);
|
|
360
413
|
} else if (installed) {
|
|
361
|
-
|
|
414
|
+
// Do NOT point at `service install` here: install deliberately does not
|
|
415
|
+
// bootstrap while a gateway is already running (two would fight over the
|
|
416
|
+
// port), so re-running it would change nothing and the advice would be a
|
|
417
|
+
// dead end. Say plainly when it becomes active, and give the command that
|
|
418
|
+
// actually loads it now.
|
|
419
|
+
console.log(` launchd: not loaded — starts at your next login`);
|
|
420
|
+
console.log(` to activate now: suveren-gateway stop && launchctl bootstrap gui/$(id -u) "${plistPath}"`);
|
|
362
421
|
}
|
|
363
422
|
console.log('');
|
|
364
423
|
await status(); // process/health/vault line
|
|
@@ -532,6 +591,28 @@ function serviceImplFor(os) {
|
|
|
532
591
|
}
|
|
533
592
|
}
|
|
534
593
|
|
|
594
|
+
/** Is something accepting TCP connections on this port? */
|
|
595
|
+
function isPortListening(port, timeoutMs = 1_000) {
|
|
596
|
+
return new Promise(resolve => {
|
|
597
|
+
const socket = createConnection({ host: '127.0.0.1', port: Number(port) });
|
|
598
|
+
const done = (result) => { socket.destroy(); resolve(result); };
|
|
599
|
+
socket.setTimeout(timeoutMs);
|
|
600
|
+
socket.once('connect', () => done(true));
|
|
601
|
+
socket.once('timeout', () => done(false));
|
|
602
|
+
socket.once('error', () => done(false));
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** Poll until the port accepts connections, or give up. */
|
|
607
|
+
async function waitForListening(port, timeoutMs) {
|
|
608
|
+
const deadline = Date.now() + timeoutMs;
|
|
609
|
+
while (Date.now() < deadline) {
|
|
610
|
+
if (await isPortListening(port, 500)) return true;
|
|
611
|
+
await sleep(300);
|
|
612
|
+
}
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
|
|
535
616
|
/** Run a command capturing output, never throwing. */
|
|
536
617
|
function runQuiet(bin, args) {
|
|
537
618
|
const r = spawnSync(bin, args, { encoding: 'utf8' });
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
"description": "List, create, update, and delete events in Google Calendar",
|
|
6
6
|
"icon": "calendar",
|
|
7
7
|
"profile": "calendar",
|
|
8
|
+
"readPolicy": {
|
|
9
|
+
"defaultAgeDays": 30
|
|
10
|
+
},
|
|
8
11
|
"npmPackage": "@humanagencyp/google-calendar-mcp",
|
|
9
12
|
"mcp": {
|
|
10
13
|
"command": "google-calendar-mcp",
|
|
@@ -12,8 +15,18 @@
|
|
|
12
15
|
},
|
|
13
16
|
"credentials": {
|
|
14
17
|
"fields": [
|
|
15
|
-
{
|
|
16
|
-
|
|
18
|
+
{
|
|
19
|
+
"key": "clientId",
|
|
20
|
+
"label": "Client ID",
|
|
21
|
+
"type": "text",
|
|
22
|
+
"placeholder": "From Google Cloud Console"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"key": "clientSecret",
|
|
26
|
+
"label": "Client Secret",
|
|
27
|
+
"type": "password",
|
|
28
|
+
"placeholder": "OAuth2 client secret"
|
|
29
|
+
}
|
|
17
30
|
],
|
|
18
31
|
"envMapping": {
|
|
19
32
|
"GOOGLE_CLIENT_ID": "clientId",
|
|
@@ -30,9 +43,15 @@
|
|
|
30
43
|
"https://www.googleapis.com/auth/calendar.events",
|
|
31
44
|
"https://www.googleapis.com/auth/calendar.readonly"
|
|
32
45
|
],
|
|
33
|
-
"credentialKeys": {
|
|
46
|
+
"credentialKeys": {
|
|
47
|
+
"clientId": "clientId",
|
|
48
|
+
"clientSecret": "clientSecret"
|
|
49
|
+
},
|
|
34
50
|
"tokenStorage": "refreshToken",
|
|
35
|
-
"extraParams": {
|
|
51
|
+
"extraParams": {
|
|
52
|
+
"access_type": "offline",
|
|
53
|
+
"prompt": "consent"
|
|
54
|
+
}
|
|
36
55
|
},
|
|
37
56
|
"contextDiscovery": {
|
|
38
57
|
"allowed_calendars": {
|
|
@@ -53,52 +72,103 @@
|
|
|
53
72
|
"toolGating": {
|
|
54
73
|
"default": {
|
|
55
74
|
"executionMapping": {},
|
|
56
|
-
"staticExecution": {
|
|
75
|
+
"staticExecution": {
|
|
76
|
+
"duration": 0,
|
|
77
|
+
"lookahead": 0
|
|
78
|
+
}
|
|
57
79
|
},
|
|
58
80
|
"overrides": {
|
|
59
81
|
"list_calendars": {
|
|
60
82
|
"category": "read",
|
|
61
|
-
"read": {
|
|
83
|
+
"read": {
|
|
84
|
+
"resourceBound": "allowed_calendars",
|
|
85
|
+
"resultResourcePath": "id"
|
|
86
|
+
}
|
|
62
87
|
},
|
|
63
88
|
"list_events": {
|
|
64
89
|
"category": "read",
|
|
65
|
-
"read": {
|
|
90
|
+
"read": {
|
|
91
|
+
"resourceBound": "allowed_calendars",
|
|
92
|
+
"resourceArg": "calendarId",
|
|
93
|
+
"resourceDefault": "primary",
|
|
94
|
+
"ageField": "read_age_days",
|
|
95
|
+
"ageFloorArg": "timeMin",
|
|
96
|
+
"ageFloorFormat": "iso"
|
|
97
|
+
}
|
|
66
98
|
},
|
|
67
99
|
"get_event": {
|
|
68
100
|
"category": "read",
|
|
69
|
-
"read": {
|
|
101
|
+
"read": {
|
|
102
|
+
"resourceBound": "allowed_calendars",
|
|
103
|
+
"resourceArg": "calendarId",
|
|
104
|
+
"resourceDefault": "primary",
|
|
105
|
+
"ageField": "read_age_days",
|
|
106
|
+
"resultDatePath": [
|
|
107
|
+
"start.dateTime",
|
|
108
|
+
"start.date"
|
|
109
|
+
]
|
|
110
|
+
}
|
|
70
111
|
},
|
|
71
112
|
"free_busy": {
|
|
72
113
|
"category": "read",
|
|
73
|
-
"read": {
|
|
114
|
+
"read": {
|
|
115
|
+
"resourceBound": "allowed_calendars",
|
|
116
|
+
"resourceArrayArg": "calendarIds",
|
|
117
|
+
"resourceDefault": "primary",
|
|
118
|
+
"ageField": "read_age_days",
|
|
119
|
+
"ageFloorArg": "timeMin",
|
|
120
|
+
"ageFloorFormat": "iso"
|
|
121
|
+
}
|
|
74
122
|
},
|
|
75
123
|
"create_event": {
|
|
76
124
|
"executionMapping": {
|
|
77
125
|
"duration_minutes": "duration",
|
|
78
126
|
"lookahead_days": "lookahead",
|
|
79
127
|
"attendees": [
|
|
80
|
-
{
|
|
81
|
-
|
|
128
|
+
{
|
|
129
|
+
"field": "allowed_attendees",
|
|
130
|
+
"transform": "join"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"field": "allowed_domains",
|
|
134
|
+
"transform": "join_domains"
|
|
135
|
+
}
|
|
82
136
|
],
|
|
83
137
|
"calendarId": "allowed_calendars"
|
|
84
138
|
},
|
|
85
|
-
"staticExecution": {
|
|
139
|
+
"staticExecution": {
|
|
140
|
+
"action_type": "booking"
|
|
141
|
+
}
|
|
86
142
|
},
|
|
87
143
|
"update_event": {
|
|
88
144
|
"executionMapping": {
|
|
89
145
|
"attendees": [
|
|
90
|
-
{
|
|
91
|
-
|
|
146
|
+
{
|
|
147
|
+
"field": "allowed_attendees",
|
|
148
|
+
"transform": "join"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"field": "allowed_domains",
|
|
152
|
+
"transform": "join_domains"
|
|
153
|
+
}
|
|
92
154
|
],
|
|
93
155
|
"calendarId": "allowed_calendars"
|
|
94
156
|
},
|
|
95
|
-
"staticExecution": {
|
|
157
|
+
"staticExecution": {
|
|
158
|
+
"action_type": "booking",
|
|
159
|
+
"duration": 0,
|
|
160
|
+
"lookahead": 0
|
|
161
|
+
}
|
|
96
162
|
},
|
|
97
163
|
"delete_event": {
|
|
98
164
|
"executionMapping": {
|
|
99
165
|
"calendarId": "allowed_calendars"
|
|
100
166
|
},
|
|
101
|
-
"staticExecution": {
|
|
167
|
+
"staticExecution": {
|
|
168
|
+
"action_type": "delete",
|
|
169
|
+
"duration": 0,
|
|
170
|
+
"lookahead": 0
|
|
171
|
+
}
|
|
102
172
|
}
|
|
103
173
|
}
|
|
104
174
|
},
|
|
@@ -108,22 +178,46 @@
|
|
|
108
178
|
"description": "List and read events, check free/busy. No create, update, or delete.",
|
|
109
179
|
"risk": "low",
|
|
110
180
|
"mode": "automatic",
|
|
111
|
-
"bounds": {
|
|
112
|
-
|
|
181
|
+
"bounds": {
|
|
182
|
+
"booking_daily_max": "0",
|
|
183
|
+
"booking_duration_max": "0",
|
|
184
|
+
"lookahead_days_max": "0"
|
|
185
|
+
},
|
|
186
|
+
"context": {
|
|
187
|
+
"allowed_calendars": "primary",
|
|
188
|
+
"allowed_attendees": "",
|
|
189
|
+
"allowed_domains": ""
|
|
190
|
+
},
|
|
113
191
|
"intent": "Allow the agent to read the primary calendar (only) to help with scheduling suggestions. No create or modify. To read other calendars, add them to allowed_calendars.",
|
|
114
192
|
"ttl": 2592000,
|
|
115
|
-
"tags": [
|
|
193
|
+
"tags": [
|
|
194
|
+
"read-only",
|
|
195
|
+
"30 days"
|
|
196
|
+
]
|
|
116
197
|
},
|
|
117
198
|
{
|
|
118
199
|
"name": "Book with Review",
|
|
119
200
|
"description": "Read events and propose new bookings. Every create/update/delete requires your approval.",
|
|
120
201
|
"risk": "high",
|
|
121
202
|
"mode": "review",
|
|
122
|
-
"bounds": {
|
|
123
|
-
|
|
203
|
+
"bounds": {
|
|
204
|
+
"booking_daily_max": "3",
|
|
205
|
+
"booking_duration_max": "120",
|
|
206
|
+
"lookahead_days_max": "30"
|
|
207
|
+
},
|
|
208
|
+
"context": {
|
|
209
|
+
"allowed_calendars": "primary",
|
|
210
|
+
"allowed_attendees": "",
|
|
211
|
+
"allowed_domains": ""
|
|
212
|
+
},
|
|
124
213
|
"intent": "Read my calendar and propose bookings. Every create, update, or delete requires my review — I see the title, time, duration, and attendees before it goes through.",
|
|
125
214
|
"ttl": 2592000,
|
|
126
|
-
"tags": [
|
|
215
|
+
"tags": [
|
|
216
|
+
"3 bookings/day",
|
|
217
|
+
"2h max",
|
|
218
|
+
"30d lookahead",
|
|
219
|
+
"review mode"
|
|
220
|
+
]
|
|
127
221
|
}
|
|
128
222
|
],
|
|
129
223
|
"setupHint": "Create OAuth credentials at Google Cloud Console and enable the Google Calendar API.",
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "deploy-github",
|
|
3
|
+
"name": "Deploy (GitHub)",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Make an already-built version live, under signed authority",
|
|
6
|
+
"icon": "wrench",
|
|
7
|
+
"profile": "deploy",
|
|
8
|
+
"npmPackage": "@humanagencyp/deploy-mcp",
|
|
9
|
+
"mcp": {
|
|
10
|
+
"command": "npx",
|
|
11
|
+
"args": [
|
|
12
|
+
"-y",
|
|
13
|
+
"@humanagencyp/deploy-mcp@latest"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"credentials": {
|
|
17
|
+
"fields": [
|
|
18
|
+
{
|
|
19
|
+
"key": "githubToken",
|
|
20
|
+
"label": "GitHub token",
|
|
21
|
+
"type": "password",
|
|
22
|
+
"placeholder": "github_pat_..."
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"envMapping": {
|
|
26
|
+
"GITHUB_TOKEN": "githubToken"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"oauth": null,
|
|
30
|
+
"toolGating": {
|
|
31
|
+
"default": {
|
|
32
|
+
"executionMapping": {},
|
|
33
|
+
"staticExecution": {},
|
|
34
|
+
"category": "disabled"
|
|
35
|
+
},
|
|
36
|
+
"overrides": {
|
|
37
|
+
"list_deployments": {
|
|
38
|
+
"category": "read",
|
|
39
|
+
"readGovernance": "none",
|
|
40
|
+
"readGovernanceReason": "Returns build metadata and the host's own deployment URLs. No source, no build output, no user content. Scoped to permitted repositories.",
|
|
41
|
+
"read": {
|
|
42
|
+
"resourceBound": "allowed_repos",
|
|
43
|
+
"resourceArg": "repo"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"get_deployment": {
|
|
47
|
+
"category": "read",
|
|
48
|
+
"readGovernance": "none",
|
|
49
|
+
"readGovernanceReason": "Returns metadata for one build — state, commit, URL. No build output.",
|
|
50
|
+
"read": {
|
|
51
|
+
"resourceBound": "allowed_repos",
|
|
52
|
+
"resourceArg": "repo"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"resolve_ref": {
|
|
56
|
+
"category": "read",
|
|
57
|
+
"readGovernance": "none",
|
|
58
|
+
"readGovernanceReason": "Returns a commit pointer only. Repository metadata, not user content.",
|
|
59
|
+
"read": {
|
|
60
|
+
"resourceBound": "allowed_repos",
|
|
61
|
+
"resourceArg": "repo"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"list_environments": {
|
|
65
|
+
"category": "read",
|
|
66
|
+
"readGovernance": "none",
|
|
67
|
+
"readGovernanceReason": "Returns environment names only. Repository configuration, needed so the owner can pick a target that exists.",
|
|
68
|
+
"read": {
|
|
69
|
+
"resourceBound": "allowed_repos",
|
|
70
|
+
"resourceArg": "repo"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"release": {
|
|
74
|
+
"executionMapping": {
|
|
75
|
+
"repo": "allowed_repos",
|
|
76
|
+
"environment": "allowed_environments",
|
|
77
|
+
"workflow": "allowed_workflows"
|
|
78
|
+
},
|
|
79
|
+
"staticExecution": {
|
|
80
|
+
"action_type": "release"
|
|
81
|
+
},
|
|
82
|
+
"contentField": "deployment_url"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"templates": [
|
|
87
|
+
{
|
|
88
|
+
"name": "Watch deployments",
|
|
89
|
+
"description": "See builds and their URLs. Cannot make anything live.",
|
|
90
|
+
"risk": "low",
|
|
91
|
+
"mode": "automatic",
|
|
92
|
+
"bounds": {
|
|
93
|
+
"release_daily_max": "0",
|
|
94
|
+
"rollback_allowed": "no"
|
|
95
|
+
},
|
|
96
|
+
"context": {
|
|
97
|
+
"allowed_repos": "",
|
|
98
|
+
"allowed_environments": "",
|
|
99
|
+
"allowed_workflows": "",
|
|
100
|
+
"allowed_branches": ""
|
|
101
|
+
},
|
|
102
|
+
"intent": "Let the agent see what has been built and whether it succeeded. It may not make anything live: a daily maximum of zero is a real limit, not an unset one. Fill in allowed_repos with the repositories it may look at.",
|
|
103
|
+
"ttl": 2592000,
|
|
104
|
+
"tags": [
|
|
105
|
+
"read-only",
|
|
106
|
+
"30 days"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "Release to production, review",
|
|
111
|
+
"description": "Make an existing build live after approval. Three a day, no rollback.",
|
|
112
|
+
"risk": "high",
|
|
113
|
+
"mode": "review",
|
|
114
|
+
"bounds": {
|
|
115
|
+
"release_daily_max": "3",
|
|
116
|
+
"rollback_allowed": "no"
|
|
117
|
+
},
|
|
118
|
+
"context": {
|
|
119
|
+
"allowed_repos": "",
|
|
120
|
+
"allowed_environments": "production",
|
|
121
|
+
"allowed_workflows": "deploy-website.yml",
|
|
122
|
+
"allowed_branches": "main"
|
|
123
|
+
},
|
|
124
|
+
"intent": "The agent may propose making a specific build live; nothing runs until I approve it. Open the build URL in the proposal and look at it before approving — that is the point of reviewing a release rather than a commit. Fill in allowed_repos, and check allowed_environments matches what the host actually calls it.",
|
|
125
|
+
"ttl": 2592000,
|
|
126
|
+
"tags": [
|
|
127
|
+
"review",
|
|
128
|
+
"production",
|
|
129
|
+
"30 days"
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"setupHint": "Use a fine-grained token, scoped to one repository.",
|
|
134
|
+
"setupGuide": [
|
|
135
|
+
{
|
|
136
|
+
"title": "Create a fine-grained token",
|
|
137
|
+
"description": "GitHub Settings, Developer settings, Personal access tokens, Fine-grained. Not a classic token — those reach everything you own.",
|
|
138
|
+
"link": "https://github.com/settings/personal-access-tokens/new"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"title": "Scope it to one repository",
|
|
142
|
+
"description": "Under Repository access pick Only select repositories, then the repo to deploy."
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"title": "Grant three permissions",
|
|
146
|
+
"description": "Actions: Read and write. Environments: Read. Contents: Read. Not Contents: Write — the agent ships commits, it never writes them."
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"title": "Paste the token below",
|
|
150
|
+
"description": "Encrypted in your local vault. The agent never sees it."
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"proposalLinks": [
|
|
154
|
+
{
|
|
155
|
+
"label": "Open this build",
|
|
156
|
+
"template": "{deployment_url}",
|
|
157
|
+
"description": "Look at exactly what would go live"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"label": "View repository",
|
|
161
|
+
"template": "https://github.com/{repo}"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
"icon": "mail",
|
|
7
7
|
"profile": "email",
|
|
8
8
|
"npmPackage": "@shinzolabs/gmail-mcp",
|
|
9
|
+
"readPolicy": {
|
|
10
|
+
"defaultAgeDays": 30
|
|
11
|
+
},
|
|
9
12
|
"mcp": {
|
|
10
13
|
"command": "gmail-mcp",
|
|
11
14
|
"args": [],
|
|
@@ -80,7 +83,10 @@
|
|
|
80
83
|
},
|
|
81
84
|
"staticExecution": {
|
|
82
85
|
"action_type": "send"
|
|
83
|
-
}
|
|
86
|
+
},
|
|
87
|
+
"blockedArgs": [
|
|
88
|
+
"raw"
|
|
89
|
+
]
|
|
84
90
|
},
|
|
85
91
|
"create_draft": {
|
|
86
92
|
"executionMapping": {
|
|
@@ -101,7 +107,10 @@
|
|
|
101
107
|
},
|
|
102
108
|
"staticExecution": {
|
|
103
109
|
"action_type": "send"
|
|
104
|
-
}
|
|
110
|
+
},
|
|
111
|
+
"blockedArgs": [
|
|
112
|
+
"raw"
|
|
113
|
+
]
|
|
105
114
|
},
|
|
106
115
|
"send_draft": {
|
|
107
116
|
"executionMapping": {},
|
|
@@ -184,7 +193,7 @@
|
|
|
184
193
|
"get_profile": {
|
|
185
194
|
"category": "read",
|
|
186
195
|
"readGovernance": "none",
|
|
187
|
-
"readGovernanceReason": "Returns the account's own address and message counts
|
|
196
|
+
"readGovernanceReason": "Returns the account's own address and message counts \u2014 the connector's own identity, no correspondence content."
|
|
188
197
|
}
|
|
189
198
|
}
|
|
190
199
|
},
|
|
@@ -227,7 +236,7 @@
|
|
|
227
236
|
"allowed_recipients": "",
|
|
228
237
|
"allowed_domains": ""
|
|
229
238
|
},
|
|
230
|
-
"intent": "Read my inbox and compose emails. Every send requires my review
|
|
239
|
+
"intent": "Read my inbox and compose emails. Every send requires my review \u2014 I see the recipient, subject, and body before it goes out.",
|
|
231
240
|
"ttl": 2592000,
|
|
232
241
|
"tags": [
|
|
233
242
|
"5 recipients/email",
|