@adtl/gateway 0.3.0 → 0.3.2

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.
Files changed (62) hide show
  1. package/README.md +59 -1
  2. package/dist/audit.d.ts +4 -2
  3. package/dist/audit.d.ts.map +1 -1
  4. package/dist/audit.js.map +1 -1
  5. package/dist/cli.js +80 -15
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config.d.ts +49 -44
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +10 -3
  10. package/dist/config.js.map +1 -1
  11. package/dist/gateway.d.ts +1 -1
  12. package/dist/gateway.js +1 -1
  13. package/dist/hooks/claudeCode.d.ts +43 -0
  14. package/dist/hooks/claudeCode.d.ts.map +1 -0
  15. package/dist/hooks/claudeCode.js +148 -0
  16. package/dist/hooks/claudeCode.js.map +1 -0
  17. package/dist/hooks/index.d.ts +4 -0
  18. package/dist/hooks/index.d.ts.map +1 -0
  19. package/dist/hooks/index.js +4 -0
  20. package/dist/hooks/index.js.map +1 -0
  21. package/dist/hooks/preset.d.ts +16 -0
  22. package/dist/hooks/preset.d.ts.map +1 -0
  23. package/dist/hooks/preset.js +32 -0
  24. package/dist/hooks/preset.js.map +1 -0
  25. package/dist/hooks/run.d.ts +9 -0
  26. package/dist/hooks/run.d.ts.map +1 -0
  27. package/dist/hooks/run.js +44 -0
  28. package/dist/hooks/run.js.map +1 -0
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/init/fromMcpJson.d.ts +41 -0
  34. package/dist/init/fromMcpJson.d.ts.map +1 -0
  35. package/dist/init/fromMcpJson.js +141 -0
  36. package/dist/init/fromMcpJson.js.map +1 -0
  37. package/dist/init/index.d.ts +2 -0
  38. package/dist/init/index.d.ts.map +1 -1
  39. package/dist/init/index.js +2 -0
  40. package/dist/init/index.js.map +1 -1
  41. package/dist/init/run.d.ts +13 -0
  42. package/dist/init/run.d.ts.map +1 -1
  43. package/dist/init/run.js +83 -11
  44. package/dist/init/run.js.map +1 -1
  45. package/dist/startup.d.ts +12 -1
  46. package/dist/startup.d.ts.map +1 -1
  47. package/dist/startup.js +27 -3
  48. package/dist/startup.js.map +1 -1
  49. package/package.json +4 -4
  50. package/src/audit.ts +4 -2
  51. package/src/cli.ts +70 -15
  52. package/src/config.ts +9 -3
  53. package/src/gateway.ts +1 -1
  54. package/src/hooks/claudeCode.ts +194 -0
  55. package/src/hooks/index.ts +3 -0
  56. package/src/hooks/preset.ts +47 -0
  57. package/src/hooks/run.ts +49 -0
  58. package/src/index.ts +1 -0
  59. package/src/init/fromMcpJson.ts +165 -0
  60. package/src/init/index.ts +2 -0
  61. package/src/init/run.ts +91 -12
  62. package/src/startup.ts +28 -4
@@ -1,4 +1,6 @@
1
1
  export { PRESETS, choosePreset, type Preset } from "./presets.js";
2
2
  export { mergeIntoDocument, ruleFromHints, suggest, type MergeReport, type ServerScan, type ServerSuggestion, type ToolSuggestion } from "./suggest.js";
3
3
  export { runInit, type InitOptions, type InitResult } from "./run.js";
4
+ export { DEFAULT_GATEWAY_NAME, gatewayEntry, importMcpServers, isGatewayEntry, toUpstream, upstreamId, type McpImport } from "./fromMcpJson.js";
5
+ export { NEW_CONFIG } from "./run.js";
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACxJ,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACxJ,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChJ,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
@@ -1,4 +1,6 @@
1
1
  export { PRESETS, choosePreset } from "./presets.js";
2
2
  export { mergeIntoDocument, ruleFromHints, suggest } from "./suggest.js";
3
3
  export { runInit } from "./run.js";
4
+ export { DEFAULT_GATEWAY_NAME, gatewayEntry, importMcpServers, isGatewayEntry, toUpstream, upstreamId } from "./fromMcpJson.js";
5
+ export { NEW_CONFIG } from "./run.js";
4
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAiF,MAAM,cAAc,CAAC;AACxJ,OAAO,EAAE,OAAO,EAAqC,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAiF,MAAM,cAAc,CAAC;AACxJ,OAAO,EAAE,OAAO,EAAqC,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,kBAAkB,CAAC;AAChJ,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
@@ -1,9 +1,16 @@
1
+ import { type McpImport } from "./fromMcpJson.js";
1
2
  import { type MergeReport } from "./suggest.js";
2
3
  export interface InitOptions {
3
4
  path: string;
4
5
  write?: boolean;
5
6
  env?: NodeJS.ProcessEnv;
7
+ /** An MCP client config with `mcpServers` (e.g. Claude Code's .mcp.json) to import upstreams from. */
8
+ from?: string;
9
+ /** Name for the gateway's entry in that client config. Default `adtl`. */
10
+ gatewayName?: string;
6
11
  }
12
+ /** Starting point when `--from` creates adtl.yaml. */
13
+ export declare const NEW_CONFIG = "# ADTL config, drafted by `adtl-gateway init --from`. Review every rule marked \"review\".\n#\n# For every tool, say what its result is (integrity, confidentiality) and where\n# calling it can send data (egress). Anything left out gets the defaults below.\n\ndefaults:\n integrity: untrusted\n confidentiality: private\n\npolicy:\n default: allow\n rules:\n - name: no-public-write-after-untrusted\n when:\n session.integrity: untrusted\n tool.egress: [public, external, unknown]\n then: ask\n reason: Session has read untrusted content; confirm before sending data out\n\n - name: private-stays-private\n when:\n session.confidentiality: [private, secret]\n tool.egress: public\n then: block\n reason: Private data must not reach a public tool\n\ngateway:\n upstreams: {}\n";
7
14
  export interface InitResult {
8
15
  /** The updated adtl.yaml. */
9
16
  text: string;
@@ -13,6 +20,12 @@ export interface InitResult {
13
20
  id: string;
14
21
  error: string;
15
22
  }[];
23
+ /** With `from`: what was imported, and the rewritten client config. */
24
+ mcp?: McpImport & {
25
+ path: string;
26
+ };
27
+ /** True if adtl.yaml didn't exist and was drafted from scratch. */
28
+ created?: boolean;
16
29
  }
17
30
  export declare function runInit(opts: InitOptions): Promise<InitResult>;
18
31
  //# sourceMappingURL=run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/init/run.ts"],"names":[],"mappings":"AAeA,OAAO,EAA8B,KAAK,WAAW,EAAmB,MAAM,cAAc,CAAC;AAE7F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,uEAAuE;IACvE,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzC;AAwBD,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAyBpE"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/init/run.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAA8B,KAAK,WAAW,EAAmB,MAAM,cAAc,CAAC;AAE7F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,sGAAsG;IACtG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD,sDAAsD;AACtD,eAAO,MAAM,UAAU,g1BA4BtB,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,uEAAuE;IACvE,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxC,uEAAuE;IACvE,GAAG,CAAC,EAAE,SAAS,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAwBD,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAwDpE"}
package/dist/init/run.js CHANGED
@@ -2,16 +2,54 @@
2
2
  * `adtl-gateway init`: connect to every upstream in adtl.yaml, list its
3
3
  * tools, and draft a labeling rule for each tool not configured yet.
4
4
  *
5
+ * With `from` (e.g. `.mcp.json`), the client's MCP servers are first imported
6
+ * into gateway.upstreams (see fromMcpJson.ts), and adtl.yaml is created if it
7
+ * doesn't exist yet.
8
+ *
5
9
  * Without `write`, the updated file is only returned (the CLI prints it).
6
10
  * With `write`, the original is kept as `<file>.bak` and the file is updated
7
- * in place. Existing entries and comments are never changed.
11
+ * in place; with `from`, the client config is rewritten to use the gateway,
12
+ * also keeping a `.bak`. Existing entries and comments are never changed.
8
13
  */
9
14
  import { readFile, writeFile } from "node:fs/promises";
10
- import { dirname } from "node:path";
15
+ import { dirname, resolve } from "node:path";
11
16
  import { parseDocument } from "yaml";
12
17
  import { expandUpstream } from "../config.js";
13
- import { connectUpstream, loadGatewayConfig } from "../startup.js";
18
+ import { GatewayConfigError, connectUpstream, parseGatewayConfigText } from "../startup.js";
19
+ import { importMcpServers } from "./fromMcpJson.js";
14
20
  import { mergeIntoDocument, suggest } from "./suggest.js";
21
+ /** Don't fold long values (paths, commands) across lines. */
22
+ const YAML_OPTIONS = { lineWidth: 0 };
23
+ /** Starting point when `--from` creates adtl.yaml. */
24
+ export const NEW_CONFIG = `# ADTL config, drafted by \`adtl-gateway init --from\`. Review every rule marked "review".
25
+ #
26
+ # For every tool, say what its result is (integrity, confidentiality) and where
27
+ # calling it can send data (egress). Anything left out gets the defaults below.
28
+
29
+ defaults:
30
+ integrity: untrusted
31
+ confidentiality: private
32
+
33
+ policy:
34
+ default: allow
35
+ rules:
36
+ - name: no-public-write-after-untrusted
37
+ when:
38
+ session.integrity: untrusted
39
+ tool.egress: [public, external, unknown]
40
+ then: ask
41
+ reason: Session has read untrusted content; confirm before sending data out
42
+
43
+ - name: private-stays-private
44
+ when:
45
+ session.confidentiality: [private, secret]
46
+ tool.egress: public
47
+ then: block
48
+ reason: Private data must not reach a public tool
49
+
50
+ gateway:
51
+ upstreams: {}
52
+ `;
15
53
  async function listAllTools(client) {
16
54
  const tools = [];
17
55
  let cursor;
@@ -35,9 +73,36 @@ async function scan(id, connect) {
35
73
  }
36
74
  export async function runInit(opts) {
37
75
  const env = opts.env ?? process.env;
38
- const loaded = await loadGatewayConfig(opts.path);
76
+ const path = resolve(opts.path);
77
+ let original;
78
+ try {
79
+ original = await readFile(path, "utf8");
80
+ }
81
+ catch (err) {
82
+ if (err.code !== "ENOENT" || !opts.from) {
83
+ throw new GatewayConfigError(`Cannot read config file ${path}: ${err.message}`);
84
+ }
85
+ }
86
+ const doc = parseDocument(original ?? NEW_CONFIG);
87
+ let mcp;
88
+ if (opts.from) {
89
+ const mcpPath = resolve(opts.from);
90
+ let mcpText;
91
+ try {
92
+ mcpText = await readFile(mcpPath, "utf8");
93
+ }
94
+ catch (err) {
95
+ throw new GatewayConfigError(`Cannot read ${mcpPath}: ${err.message}`);
96
+ }
97
+ try {
98
+ mcp = { path: mcpPath, ...importMcpServers(mcpText, mcpPath, doc, path, opts.gatewayName) };
99
+ }
100
+ catch (err) {
101
+ throw new GatewayConfigError(err.message);
102
+ }
103
+ }
104
+ const loaded = parseGatewayConfigText(doc.toString(YAML_OPTIONS), path);
39
105
  const baseDir = dirname(loaded.path);
40
- const original = await readFile(loaded.path, "utf8");
41
106
  const ids = Object.keys(loaded.gateway.upstreams);
42
107
  const settled = await Promise.allSettled(ids.map((id) => scan(id, () => connectUpstream(id, expandUpstream(id, loaded.gateway.upstreams[id], env), baseDir))));
43
108
  const scans = [];
@@ -48,13 +113,20 @@ export async function runInit(opts) {
48
113
  else
49
114
  failed.push({ id: ids[i], error: s.reason.message });
50
115
  });
51
- const doc = parseDocument(original);
52
116
  const reports = mergeIntoDocument(doc, scans.map((s) => suggest(s)));
53
- const text = doc.toString();
54
- if (opts.write && text !== original) {
55
- await writeFile(`${loaded.path}.bak`, original, "utf8");
56
- await writeFile(loaded.path, text, "utf8");
117
+ const text = doc.toString(YAML_OPTIONS);
118
+ if (opts.write) {
119
+ if (original === undefined)
120
+ await writeFile(path, text, "utf8");
121
+ else if (text !== original) {
122
+ await writeFile(`${path}.bak`, original, "utf8");
123
+ await writeFile(path, text, "utf8");
124
+ }
125
+ if (mcp?.changed) {
126
+ await writeFile(`${mcp.path}.bak`, await readFile(mcp.path, "utf8"), "utf8");
127
+ await writeFile(mcp.path, mcp.text, "utf8");
128
+ }
57
129
  }
58
- return { text, reports, failed };
130
+ return { text, reports, failed, ...(mcp ? { mcp } : {}), ...(original === undefined ? { created: true } : {}) };
59
131
  }
60
132
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/init/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/init/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG7C,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAkB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAqC,MAAM,cAAc,CAAC;AAY7F,6DAA6D;AAC7D,MAAM,YAAY,GAAG,EAAE,SAAS,EAAE,CAAC,EAAW,CAAC;AAE/C,sDAAsD;AACtD,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BzB,CAAC;AAcF,KAAK,UAAU,YAAY,CAAC,MAAc;IACxC,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,IAAI,MAA0B,CAAC;IAC/B,GAAG,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC,QAAQ,MAAM,EAAE;IACjB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,EAAU,EAAE,OAA8B;IAC5D,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,IAAI,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC;IAChI,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiB;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,QAA4B,CAAC;IACjC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACnE,MAAM,IAAI,kBAAkB,CAAC,2BAA2B,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7F,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC;IAElD,IAAI,GAAsB,CAAC;IAC3B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,kBAAkB,CAAC,eAAe,OAAO,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC;YACH,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,kBAAkB,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAE,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CACtH,CAAC;IACF,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;;YAC7C,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,KAAK,EAAG,CAAC,CAAC,MAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACxC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;aAC3D,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,SAAS,CAAC,GAAG,IAAI,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACjD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;YACjB,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;YAC7E,MAAM,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAClH,CAAC"}
package/dist/startup.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import type { AdtlConfig } from "@adtl/labels";
2
+ import { type AdtlConfig } from "@adtl/labels";
3
3
  import { ApprovalBroker } from "./approvals.js";
4
4
  import { type GatewayConfig, type Upstream } from "./config.js";
5
5
  import { AdtlGateway, type GatewayLogger } from "./gateway.js";
@@ -12,11 +12,22 @@ export interface LoadedConfig {
12
12
  gateway: GatewayConfig;
13
13
  }
14
14
  export declare function loadGatewayConfig(path: string): Promise<LoadedConfig>;
15
+ /** Validate adtl.yaml text; `path` is where it lives (relative paths in it resolve against its directory). */
16
+ export declare function parseGatewayConfigText(text: string, path: string): LoadedConfig;
15
17
  /** Path of the bundled adtl-interceptors CLI. */
16
18
  export declare function bundledInterceptorsCli(): string;
17
19
  export declare function connectUpstream(id: string, u: Upstream, baseDir: string): Promise<Client>;
18
20
  /** Build the approval broker from `gateway.approvals`, or undefined if not configured. */
19
21
  export declare function createApprovals(cfg: GatewayConfig, env: NodeJS.ProcessEnv, log: GatewayLogger): ApprovalBroker | undefined;
22
+ /**
23
+ * Under Claude Code, which passes `CLAUDE_CODE_SESSION_ID` to stdio MCP
24
+ * servers, the gateway uses that id and keeps session labels in files, so the
25
+ * Claude Code hooks (`adtl-gateway hook`) add to the same session label.
26
+ */
27
+ export declare function sharedSession(env: NodeJS.ProcessEnv): {
28
+ sessionId: string;
29
+ dir: string;
30
+ } | undefined;
20
31
  export interface StartedGateway {
21
32
  gateway: AdtlGateway;
22
33
  close(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAIhF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA2B3E;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,IAAI,MAAM,CAI/C;AAaD,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO/F;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,cAAc,GAAG,SAAS,CAiB1H;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAO,GAC7D,OAAO,CAAC,cAAc,CAAC,CAgEzB"}
1
+ {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGnE,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAIhF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAS3E;AAED,8GAA8G;AAC9G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAqB/E;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,IAAI,MAAM,CAI/C;AAaD,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO/F;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,cAAc,GAAG,SAAS,CAiB1H;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGpG;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAO,GAC7D,OAAO,CAAC,cAAc,CAAC,CAwEzB"}
package/dist/startup.js CHANGED
@@ -9,6 +9,7 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
9
9
  import { StdioClientTransport, getDefaultEnvironment } from "@modelcontextprotocol/sdk/client/stdio.js";
10
10
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
11
11
  import { INTERCEPTORS_EXTENSION, LABEL_INTERCEPTOR, POLICY_INTERCEPTOR, parseConfigText } from "@adtl/interceptors";
12
+ import { defaultSessionsDir } from "@adtl/labels";
12
13
  import { parse as parseYaml } from "yaml";
13
14
  import { ZodError } from "zod";
14
15
  import { ApprovalBroker } from "./approvals.js";
@@ -33,6 +34,11 @@ export async function loadGatewayConfig(path) {
33
34
  catch (err) {
34
35
  throw new GatewayConfigError(`Cannot read config file ${abs}: ${err.message}`);
35
36
  }
37
+ return parseGatewayConfigText(text, abs);
38
+ }
39
+ /** Validate adtl.yaml text; `path` is where it lives (relative paths in it resolve against its directory). */
40
+ export function parseGatewayConfigText(text, path) {
41
+ const abs = resolve(path);
36
42
  let labels;
37
43
  try {
38
44
  labels = parseConfigText(text, abs);
@@ -101,6 +107,15 @@ export function createApprovals(cfg, env, log) {
101
107
  log.info(`approvals: ${notifiers.map((n) => n.name).join(", ")} (timeout ${a.timeoutSeconds}s)`);
102
108
  return new ApprovalBroker({ notifiers, timeoutMs: a.timeoutSeconds * 1000, log });
103
109
  }
110
+ /**
111
+ * Under Claude Code, which passes `CLAUDE_CODE_SESSION_ID` to stdio MCP
112
+ * servers, the gateway uses that id and keeps session labels in files, so the
113
+ * Claude Code hooks (`adtl-gateway hook`) add to the same session label.
114
+ */
115
+ export function sharedSession(env) {
116
+ const sessionId = env.CLAUDE_CODE_SESSION_ID?.trim();
117
+ return sessionId ? { sessionId, dir: defaultSessionsDir(env) } : undefined;
118
+ }
104
119
  export async function startGateway(loaded, opts = {}) {
105
120
  const env = opts.env ?? process.env;
106
121
  const baseDir = dirname(loaded.path);
@@ -109,9 +124,15 @@ export async function startGateway(loaded, opts = {}) {
109
124
  const closeAll = () => Promise.allSettled(clients.map((c) => c.close())).then(() => undefined);
110
125
  try {
111
126
  // 1. Interceptor server (out of process, per the Interceptors WG).
112
- const icfg = loaded.gateway.interceptors
113
- ? expandUpstream("interceptors", loaded.gateway.interceptors, env)
114
- : { command: process.execPath, args: [bundledInterceptorsCli(), "--config", loaded.path], env: {} };
127
+ const shared = sharedSession(env);
128
+ const custom = loaded.gateway.interceptors && expandUpstream("interceptors", loaded.gateway.interceptors, env);
129
+ const icfg = custom
130
+ ? { ...custom, env: { ...custom.env, ...(shared ? { ADTL_SESSIONS_DIR: shared.dir } : {}) } }
131
+ : {
132
+ command: process.execPath,
133
+ args: [bundledInterceptorsCli(), "--config", loaded.path, ...(shared ? ["--sessions-dir", shared.dir] : [])],
134
+ env: {},
135
+ };
115
136
  const interceptors = await connectUpstream("interceptors", icfg, baseDir);
116
137
  clients.push(interceptors);
117
138
  if (!interceptors.getServerCapabilities()?.extensions?.[INTERCEPTORS_EXTENSION]) {
@@ -127,6 +148,8 @@ export async function startGateway(loaded, opts = {}) {
127
148
  const audit = loaded.gateway.mode === "audit";
128
149
  const invoker = new InterceptorInvoker(bound, loaded.gateway.interceptorTimeoutMs, audit ? "audit" : undefined);
129
150
  log.info(`interceptors: ${names.join(", ")}`);
151
+ if (shared)
152
+ log.info(`sharing session labels with Claude Code hooks (${shared.dir})`);
130
153
  if (audit)
131
154
  log.warn("audit mode: calls are logged but never stopped or changed");
132
155
  // 2. Upstream servers. One failing upstream does not stop the others.
@@ -152,6 +175,7 @@ export async function startGateway(loaded, opts = {}) {
152
175
  const auditLog = loaded.gateway.audit ? new JsonlAuditLog(resolve(baseDir, loaded.gateway.audit)) : undefined;
153
176
  const approvals = createApprovals(loaded.gateway, env, log);
154
177
  const gateway = new AdtlGateway({
178
+ ...(shared ? { sessionId: shared.sessionId } : {}),
155
179
  upstreams,
156
180
  invoker,
157
181
  ...(auditLog ? { audit: auditLog } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AACxG,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEpH,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,cAAc,GAIf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAsB,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAQD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,kBAAkB,CAAC,2BAA2B,GAAG,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,kBAAkB,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAA0B,CAAC;IAC7D,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,kBAAkB,CAAC,GAAG,GAAG,8EAA8E,CAAC,CAAC;IACrH,CAAC;IACD,IAAI,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;IAChF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnG,MAAM,IAAI,kBAAkB,CAAC,GAAG,GAAG,6BAA6B,QAAQ,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,sBAAsB;IACpC,+FAA+F;IAC/F,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;IACtF,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,cAAc,CAAC,CAAgB,EAAE,OAAe;IACvD,OAAO,IAAI,oBAAoB,CAAC;QAC9B,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,6FAA6F;QAC7F,GAAG,EAAE,EAAE,GAAG,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE;QAC7C,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAU,EAAE,CAAW,EAAE,OAAe;IAC5E,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,IAAI,6BAA6B,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5F,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,eAAe,CAAC,GAAkB,EAAE,GAAsB,EAAE,GAAkB;IAC5F,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACX,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/F,GAAG,CAAC,IAAI,CAAC,2IAA2I,CAAC,CAAC;QACxJ,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACZ,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACzH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,8FAA8F,CAAC,CAAC;IAC/I,GAAG,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC;IACjG,OAAO,IAAI,cAAc,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,cAAc,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;AACpF,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAoB,EACpB,OAA4D,EAAE;IAE9D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC;IAC7J,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAE/F,IAAI,CAAC;QACH,mEAAmE;QACnE,MAAM,IAAI,GAAkB,MAAM,CAAC,OAAO,CAAC,YAAY;YACrD,CAAC,CAAC,cAAc,CAAC,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;YAClE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,sBAAsB,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;QACtG,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3B,IAAI,CAAC,YAAY,CAAC,qBAAqB,EAAE,EAAE,UAAU,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,kBAAkB,CAAC,+CAA+C,sBAAsB,YAAY,CAAC,CAAC;QAClH,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAClD,KAAK,MAAM,QAAQ,IAAI,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,kBAAkB,CAAC,yCAAyC,QAAQ,gCAAgC,CAAC,CAAC;YAClH,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChH,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;QAEjF,sEAAsE;QACtE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAE,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CACtG,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACvB,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;YACnB,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACtB,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC/B,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,sFAAsF,CAAC,CAAC;gBAClH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CAAC,kCAAkC,EAAE,MAAO,CAAC,CAAC,MAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM,IAAI,kBAAkB,CAAC,uCAAuC,CAAC,CAAC;QAChG,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE3D,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9G,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC;YAC9B,SAAS;YACT,OAAO;YACP,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,MAAM,EAAE,GAAG;SACZ,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,QAAQ,EAAE,CAAC;QACjB,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adtl/gateway",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Experimental: MCP gateway that labels every tool result and blocks risky tool calls using ADTL trust labels",
5
5
  "keywords": [
6
6
  "mcp",
@@ -24,7 +24,7 @@
24
24
  }
25
25
  },
26
26
  "bin": {
27
- "adtl-gateway": "./dist/cli.js"
27
+ "adtl-gateway": "dist/cli.js"
28
28
  },
29
29
  "files": [
30
30
  "dist",
@@ -46,8 +46,8 @@
46
46
  "url": "https://github.com/probita-ai/adtl/issues"
47
47
  },
48
48
  "dependencies": {
49
- "@adtl/interceptors": "0.3.0",
50
- "@adtl/labels": "0.3.0",
49
+ "@adtl/interceptors": "0.3.2",
50
+ "@adtl/labels": "0.3.2",
51
51
  "@modelcontextprotocol/sdk": "1.31.0",
52
52
  "nodemailer": "10.0.12",
53
53
  "yaml": "2.9.1",
package/src/audit.ts CHANGED
@@ -16,8 +16,10 @@ export interface AuditEntry {
16
16
  tool?: string;
17
17
  resource?: string;
18
18
  prompt?: string;
19
- /** Final outcome of the call. */
20
- outcome: "forwarded" | "blocked" | "upstream_error";
19
+ /** Final outcome of the call. "asked": handed to Claude Code's permission prompt by the hook. */
20
+ outcome: "forwarded" | "blocked" | "asked" | "upstream_error";
21
+ /** Present when the entry was written by the Claude Code hook rather than the gateway. */
22
+ via?: "claude-code-hook";
21
23
  /** The policy's decision. In audit mode a call can be forwarded with decision "ask" or "block". */
22
24
  decision?: string;
23
25
  /** Present when the gateway ran in audit mode: nothing was stopped or changed. */
package/src/cli.ts CHANGED
@@ -4,7 +4,8 @@
4
4
  * servers through ADTL's interceptors.
5
5
  *
6
6
  * adtl-gateway --config adtl.yaml [--audit]
7
- * adtl-gateway init --config adtl.yaml [--write]
7
+ * adtl-gateway init --config adtl.yaml [--from .mcp.json] [--write]
8
+ * adtl-gateway hook --config adtl.yaml [--gateway-server adtl]
8
9
  *
9
10
  * Point your MCP client (e.g. Claude Code's .mcp.json) at this command.
10
11
  * Logs go to stderr; stdout carries MCP JSON-RPC only.
@@ -12,11 +13,13 @@
12
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
14
  import { EnvExpansionError } from "./config.js";
14
15
  import { GATEWAY_VERSION } from "./gateway.js";
16
+ import { runHook } from "./hooks/run.js";
15
17
  import { runInit, type InitResult } from "./init/run.js";
16
18
  import { GatewayConfigError, loadGatewayConfig, startGateway } from "./startup.js";
17
19
 
18
20
  const USAGE = `Usage: adtl-gateway --config <adtl.yaml> [--audit]
19
- adtl-gateway init --config <adtl.yaml> [--write]
21
+ adtl-gateway init --config <adtl.yaml> [--from <.mcp.json>] [--write]
22
+ adtl-gateway hook --config <adtl.yaml> [--gateway-server <name>]
20
23
 
21
24
  Runs an MCP server over stdio that forwards tool calls to the upstream
22
25
  servers in the config, checking and labeling each call with ADTL.
@@ -32,11 +35,30 @@ init:
32
35
  for each tool the config doesn't cover yet (presets for GitHub,
33
36
  filesystem and fetch; MCP tool hints otherwise). Existing entries are
34
37
  never changed. Prints the updated config; review it before using it.
38
+ --from <file> First import the MCP servers of a client config (Claude
39
+ Code's .mcp.json, or any file with "mcpServers") into
40
+ gateway.upstreams, creating the config file if needed.
41
+ With --write, that file is changed to run the gateway
42
+ in place of the imported servers (original kept as .bak).
35
43
  --write Update the config file in place (original kept as .bak).
44
+
45
+ hook:
46
+ The Claude Code hook for PreToolUse, PostToolUse and PostToolUseFailure.
47
+ Labels built-in tools (WebFetch, Read, Bash, ...) and MCP servers outside
48
+ the gateway, and runs the same policy on them, sharing the session label
49
+ with the gateway. Reads the hook event from stdin.
50
+ --gateway-server <name>
51
+ The gateway's name in Claude Code's MCP config; its
52
+ tools are checked by the gateway and skipped here.
53
+ Default: adtl.
54
+
36
55
  -h, --help Show this help.`;
37
56
 
38
57
  interface Args {
39
58
  init?: boolean;
59
+ from?: string;
60
+ hook?: boolean;
61
+ gatewayServer?: string;
40
62
  write?: boolean;
41
63
  config?: string;
42
64
  audit?: boolean;
@@ -49,12 +71,15 @@ function parseArgs(argv: string[]): Args {
49
71
  for (let i = 0; i < argv.length; i++) {
50
72
  const a = argv[i];
51
73
  if (i === 0 && a === "init") out.init = true;
74
+ else if (i === 0 && a === "hook") out.hook = true;
75
+ else if (a === "--gateway-server" && out.hook) out.gatewayServer = argv[++i];
52
76
  else if (a === "-h" || a === "--help") out.help = true;
53
77
  else if (a === "-v" || a === "--version") out.version = true;
54
78
  else if (a === "-c" || a === "--config") out.config = argv[++i];
55
79
  else if (a?.startsWith("--config=")) out.config = a.slice("--config=".length);
56
80
  else if (a === "--audit") out.audit = true;
57
81
  else if (a === "--write" && out.init) out.write = true;
82
+ else if (a === "--from" && out.init) out.from = argv[++i];
58
83
  else throw new GatewayConfigError(`Unknown argument: ${a}\n\n${USAGE}`);
59
84
  }
60
85
  return out;
@@ -66,7 +91,8 @@ async function main(): Promise<void> {
66
91
  if (args.help) return void console.log(USAGE);
67
92
  if (args.version) return void console.log(GATEWAY_VERSION);
68
93
  if (!args.config) throw new GatewayConfigError(`Missing --config\n\n${USAGE}`);
69
- if (args.init) return init(args.config, args.write === true);
94
+ if (args.init) return init(args.config, args.write === true, args.from);
95
+ if (args.hook) return hook(args.config, args.gatewayServer);
70
96
 
71
97
  const loaded = await loadGatewayConfig(args.config);
72
98
  if (args.audit) loaded.gateway.mode = "audit";
@@ -93,26 +119,54 @@ async function main(): Promise<void> {
93
119
  }
94
120
 
95
121
  function summarize(r: InitResult, path: string, write: boolean): string {
96
- const lines = r.reports.map((s) => {
122
+ const lines: string[] = [];
123
+ if (r.mcp) {
124
+ const m = r.mcp;
125
+ for (const i of m.imported) lines.push(` imported ${i.name}${i.id !== i.name ? ` as ${i.id}` : ""} from ${m.path}`);
126
+ for (const k of m.kept) lines.push(` ${k.name}: already in the config as ${k.id}, kept as it is`);
127
+ for (const s of m.skipped) lines.push(` ${s.name}: left in ${m.path} (${s.reason})`);
128
+ if (!m.imported.length && !m.kept.length) lines.push(` nothing to import from ${m.path}`);
129
+ }
130
+ if (r.created) lines.push(` ${write ? "created" : "would create"} ${path}`);
131
+ lines.push(...r.reports.map((s) => {
97
132
  const parts = [`${s.added.length} tools added`];
98
133
  if (s.kept.length) parts.push(`${s.kept.length} kept`);
99
134
  if (s.addedDefaults) parts.push("defaults added");
100
135
  if (s.stale.length) parts.push(`no longer offered: ${s.stale.join(", ")}`);
101
136
  return ` ${s.id} (${s.preset ? `preset ${s.preset}` : "from tool hints, review"}): ${parts.join("; ")}`;
102
- });
137
+ }));
103
138
  for (const f of r.failed) lines.push(` ${f.id}: could not connect, skipped (${f.error})`);
104
- const changed = r.reports.some((s) => s.added.length || s.addedDefaults);
105
- const tail = !changed
106
- ? "Nothing to add."
107
- : write
108
- ? `Updated ${path} (original saved as ${path}.bak). Review every line marked "review".`
109
- : "Nothing written. Review the config above, then re-run with --write.";
139
+ const changed = r.created || r.mcp?.changed || r.reports.some((s) => s.added.length || s.addedDefaults);
140
+ let tail: string;
141
+ if (!changed) tail = "Nothing to add.";
142
+ else if (!write) tail = "Nothing written. Review the config above, then re-run with --write.";
143
+ else {
144
+ tail = r.created ? `Wrote ${path}.` : `Updated ${path} (original saved as ${path}.bak).`;
145
+ if (r.mcp?.changed) tail += ` ${r.mcp.path} now runs the gateway (original saved as ${r.mcp.path}.bak); restart your MCP client.`;
146
+ tail += ' Review every line marked "review".';
147
+ }
110
148
  return `${lines.join("\n")}\n${tail}`;
111
149
  }
112
150
 
113
- async function init(path: string, write: boolean): Promise<void> {
114
- const result = await runInit({ path, write });
115
- if (!write) process.stdout.write(result.text);
151
+ async function readStdin(): Promise<string> {
152
+ const chunks: Buffer[] = [];
153
+ for await (const c of process.stdin) chunks.push(c as Buffer);
154
+ return Buffer.concat(chunks).toString("utf8");
155
+ }
156
+
157
+ async function hook(config: string, gatewayServer?: string): Promise<void> {
158
+ const out = await runHook({ configPath: config, stdin: await readStdin(), ...(gatewayServer ? { gatewayServer } : {}) });
159
+ if (out.stdout) process.stdout.write(`${JSON.stringify(out.stdout)}\n`);
160
+ if (out.stderr) process.stderr.write(`${out.stderr}\n`);
161
+ process.exitCode = out.exitCode;
162
+ }
163
+
164
+ async function init(path: string, write: boolean, from?: string): Promise<void> {
165
+ const result = await runInit({ path, write, ...(from ? { from } : {}) });
166
+ if (!write) {
167
+ process.stdout.write(result.text);
168
+ if (result.mcp?.changed) process.stdout.write(`\n# ${result.mcp.path} with --write:\n${result.mcp.text.replace(/^/gm, "# ")}\n`);
169
+ }
116
170
  console.error(`[adtl-gateway] init\n${summarize(result, path, write)}`);
117
171
  if (result.failed.length && !result.reports.length) process.exitCode = 1;
118
172
  }
@@ -120,5 +174,6 @@ async function init(path: string, write: boolean): Promise<void> {
120
174
  main().catch((err: unknown) => {
121
175
  const known = err instanceof GatewayConfigError || err instanceof EnvExpansionError;
122
176
  console.error(known ? `[adtl-gateway] ${(err as Error).message}` : err);
123
- process.exit(1);
177
+ // For Claude Code hooks only exit code 2 stops the call; any other code lets it run.
178
+ process.exit(process.argv[2] === "hook" ? 2 : 1);
124
179
  });
package/src/config.ts CHANGED
@@ -21,7 +21,8 @@
21
21
  * to: you@example.com
22
22
  *
23
23
  * `${VAR}` in command, args, env, cwd, url, headers and approval settings is
24
- * replaced from the gateway's environment. A missing variable is a config error.
24
+ * replaced from the gateway's environment. A missing variable is a config error,
25
+ * unless a default is given: `${VAR:-default}`.
25
26
  */
26
27
  import { z } from "zod";
27
28
  import { EMAIL_EVENTS } from "./email.js";
@@ -125,11 +126,16 @@ export class EnvExpansionError extends Error {
125
126
  }
126
127
  }
127
128
 
128
- /** Replace `${VAR}` with values from `env`. `$${VAR}` keeps a literal `${VAR}`. */
129
+ /**
130
+ * Replace `${VAR}` with values from `env`, and `${VAR:-default}` with `default`
131
+ * when VAR is unset or empty (as Claude Code's .mcp.json does). `$${VAR}` keeps
132
+ * a literal `${VAR}`.
133
+ */
129
134
  export function expandEnv(value: string, env: NodeJS.ProcessEnv, where: string): string {
130
- return value.replace(/(\$?)\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (match, escape: string, name: string) => {
135
+ return value.replace(/(\$?)\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g, (match, escape: string, name: string, fallback?: string) => {
131
136
  if (escape) return match.slice(1);
132
137
  const v = env[name];
138
+ if (fallback !== undefined) return v === undefined || v === "" ? fallback : v;
133
139
  if (v === undefined) throw new EnvExpansionError(name, where);
134
140
  return v;
135
141
  });
package/src/gateway.ts CHANGED
@@ -51,7 +51,7 @@ import type { AuditEntry, AuditSink } from "./audit.js";
51
51
  import { TOOL_SEPARATOR } from "./config.js";
52
52
  import type { Blocked, ChainOutcome, InterceptorInvoker } from "./invoker.js";
53
53
 
54
- export const GATEWAY_VERSION = "0.3.0";
54
+ export const GATEWAY_VERSION = "0.3.2";
55
55
 
56
56
  /** `_meta` key on gateway-generated error results describing why a call was stopped. */
57
57
  export const GATEWAY_DECISION_KEY = "adtl/gateway";