@orygn/opa-mcp 0.1.9 → 0.1.10

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 (51) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +54 -9
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +1 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config.d.ts +4 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +4 -0
  9. package/dist/config.js.map +1 -1
  10. package/dist/constants.d.ts +1 -1
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +1 -1
  13. package/dist/constants.js.map +1 -1
  14. package/dist/lib/conftest-cli.d.ts +144 -0
  15. package/dist/lib/conftest-cli.d.ts.map +1 -0
  16. package/dist/lib/conftest-cli.js +224 -0
  17. package/dist/lib/conftest-cli.js.map +1 -0
  18. package/dist/lib/tool-helpers.d.ts +1 -1
  19. package/dist/lib/tool-helpers.d.ts.map +1 -1
  20. package/dist/lib/tool-helpers.js +8 -2
  21. package/dist/lib/tool-helpers.js.map +1 -1
  22. package/dist/server.d.ts.map +1 -1
  23. package/dist/server.js +14 -2
  24. package/dist/server.js.map +1 -1
  25. package/dist/tools/conftest/index.d.ts +4 -0
  26. package/dist/tools/conftest/index.d.ts.map +1 -0
  27. package/dist/tools/conftest/index.js +11 -0
  28. package/dist/tools/conftest/index.js.map +1 -0
  29. package/dist/tools/conftest/pull.d.ts +10 -0
  30. package/dist/tools/conftest/pull.d.ts.map +1 -0
  31. package/dist/tools/conftest/pull.js +83 -0
  32. package/dist/tools/conftest/pull.js.map +1 -0
  33. package/dist/tools/conftest/push.d.ts +10 -0
  34. package/dist/tools/conftest/push.d.ts.map +1 -0
  35. package/dist/tools/conftest/push.js +76 -0
  36. package/dist/tools/conftest/push.js.map +1 -0
  37. package/dist/tools/conftest/test.d.ts +21 -0
  38. package/dist/tools/conftest/test.d.ts.map +1 -0
  39. package/dist/tools/conftest/test.js +186 -0
  40. package/dist/tools/conftest/test.js.map +1 -0
  41. package/dist/tools/conftest/verify.d.ts +21 -0
  42. package/dist/tools/conftest/verify.d.ts.map +1 -0
  43. package/dist/tools/conftest/verify.js +112 -0
  44. package/dist/tools/conftest/verify.js.map +1 -0
  45. package/dist/tools/index.d.ts +11 -9
  46. package/dist/tools/index.d.ts.map +1 -1
  47. package/dist/tools/index.js +2 -0
  48. package/dist/tools/index.js.map +1 -1
  49. package/dist/types.d.ts +1 -1
  50. package/dist/types.d.ts.map +1 -1
  51. package/package.json +1 -1
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Wrapper around the optional `conftest` binary (policy testing for
3
+ * configuration files using Rego).
4
+ *
5
+ * Conftest is OPTIONAL -- only the `conftest_*` tools require it. All
6
+ * other tools work without Conftest installed. If absent, conftest tools
7
+ * return a structured `CONFTEST_NOT_FOUND` error with an install hint.
8
+ *
9
+ * Conftest exit codes:
10
+ * 0 -- all tests pass (or no failures, only warnings)
11
+ * 1 -- one or more test failures
12
+ * 2+ -- command error (bad args, policy not found, parse error, etc.)
13
+ *
14
+ * All structured output is obtained via `--output=json`; raw text output
15
+ * is never parsed.
16
+ */
17
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
18
+ import { tmpdir } from 'node:os';
19
+ import { join } from 'node:path';
20
+ import { runBinary } from './subprocess.js';
21
+ // ─── Parser → file extension map ─────────────────────────────────────────────
22
+ const PARSER_TO_EXT = {
23
+ yaml: '.yaml',
24
+ json: '.json',
25
+ toml: '.toml',
26
+ hcl1: '.hcl',
27
+ hcl2: '.hcl',
28
+ ini: '.ini',
29
+ xml: '.xml',
30
+ dotenv: '.env',
31
+ cue: '.cue',
32
+ jsonnet: '.jsonnet',
33
+ properties: '.properties',
34
+ edn: '.edn',
35
+ hocon: '.conf',
36
+ // Dockerfile is a special case -- conftest detects by filename
37
+ dockerfile: '',
38
+ };
39
+ function parserToExt(parser) {
40
+ return PARSER_TO_EXT[parser.toLowerCase()] ?? `.${parser.toLowerCase()}`;
41
+ }
42
+ // ─── ConftestCli ──────────────────────────────────────────────────────────────
43
+ /**
44
+ * Wrapper around the local `conftest` binary.
45
+ *
46
+ * Methods do not throw on conftest-side errors -- the exit code on the
47
+ * returned `SpawnResult` is the signal. Inline source is written to temp
48
+ * files/directories because conftest does not read from stdin.
49
+ */
50
+ export class ConftestCli {
51
+ config;
52
+ constructor(config) {
53
+ this.config = config;
54
+ }
55
+ /**
56
+ * Verify the binary is present and return its version string. Returns
57
+ * null if the binary is unreachable or the version output is malformed.
58
+ */
59
+ async version(signal) {
60
+ const result = await this.run(['--version'], signal);
61
+ if (result.exitCode !== 0)
62
+ return null;
63
+ // conftest --version output: "conftest (version: 0.68.2)"
64
+ const match = /conftest\s*\(version:\s*([^)]+)\)/i.exec(result.stdout) ??
65
+ /v?(\d+\.\d+\.\d+\S*)/i.exec(result.stdout);
66
+ return match?.[1]?.trim() ?? null;
67
+ }
68
+ /**
69
+ * Run `conftest test` against one or more configuration files. Always
70
+ * uses `--output=json` so output is machine-readable.
71
+ *
72
+ * When `inlineConfig` or `inlinePolicy` are provided, temp files are
73
+ * created and cleaned up automatically. Temp file paths in the JSON
74
+ * output are replaced with `<inline>` before the result is returned so
75
+ * callers never see implementation-internal paths.
76
+ */
77
+ async test(input, signal) {
78
+ return this.withTempAssets({
79
+ inlineConfig: input.inlineConfig,
80
+ inlineConfigParser: input.inlineConfigParser,
81
+ inlinePolicy: input.inlinePolicy,
82
+ }, async ({ configPath, policyDir }) => {
83
+ const args = ['test', '--output=json', '--no-color'];
84
+ // Policy source
85
+ const effectivePolicyDir = policyDir ?? input.policy;
86
+ if (effectivePolicyDir)
87
+ args.push('--policy', effectivePolicyDir);
88
+ // Namespace
89
+ if (input.allNamespaces) {
90
+ args.push('--all-namespaces');
91
+ }
92
+ else if (input.namespace) {
93
+ args.push('--namespace', input.namespace);
94
+ }
95
+ // Data directories
96
+ for (const d of input.data ?? [])
97
+ args.push('--data', d);
98
+ // Flags
99
+ if (input.combine)
100
+ args.push('--combine');
101
+ if (input.failOnWarn)
102
+ args.push('--fail-on-warn');
103
+ // Config files (positional args, must come last)
104
+ const effectiveFiles = configPath ? [configPath] : (input.files ?? []);
105
+ args.push(...effectiveFiles);
106
+ const result = await this.run(args, signal);
107
+ return this.sanitizeOutput(result, configPath, policyDir);
108
+ });
109
+ }
110
+ /**
111
+ * Run `conftest verify` -- executes the `_test.rego` tests inside the
112
+ * policy directory to verify the policies themselves.
113
+ */
114
+ async verify(input, signal) {
115
+ const args = ['verify', '--output=json', '--no-color'];
116
+ if (input.policy)
117
+ args.push('--policy', input.policy);
118
+ if (input.namespace)
119
+ args.push('--namespace', input.namespace);
120
+ for (const d of input.data ?? [])
121
+ args.push('--data', d);
122
+ return this.run(args, signal);
123
+ }
124
+ /**
125
+ * Pull policies from a remote OCI or Git location into a local
126
+ * directory. Stdout is minimal; errors go to stderr.
127
+ */
128
+ async pull(input, signal) {
129
+ const args = ['pull', input.url];
130
+ if (input.policy)
131
+ args.push('--policy', input.policy);
132
+ return this.run(args, signal);
133
+ }
134
+ /**
135
+ * Push the local policy bundle to a remote OCI registry. Uses
136
+ * credentials from the host environment (docker login, ORAS, etc.).
137
+ */
138
+ async push(input, signal) {
139
+ const args = ['push', input.repository];
140
+ if (input.policy)
141
+ args.push('--policy', input.policy);
142
+ return this.run(args, signal);
143
+ }
144
+ /**
145
+ * Run `conftest` with the given argv. Tools should prefer the typed
146
+ * methods above; this is the escape hatch for unusual invocations.
147
+ */
148
+ async run(args, signal) {
149
+ const opts = {
150
+ args,
151
+ timeoutMs: this.config.subprocessTimeoutMs,
152
+ };
153
+ if (signal !== undefined)
154
+ opts.signal = signal;
155
+ return runBinary(this.config.conftestBinary, opts);
156
+ }
157
+ // ─── Internal: temp file / directory management ──────────────────────────
158
+ /**
159
+ * Create temp assets for inline inputs, run `fn`, then clean up.
160
+ * Returns whatever `fn` returns.
161
+ */
162
+ async withTempAssets(opts, fn) {
163
+ const temps = [];
164
+ const paths = {};
165
+ try {
166
+ if (opts.inlineConfig !== undefined) {
167
+ const ext = opts.inlineConfigParser === 'dockerfile'
168
+ ? ''
169
+ : parserToExt(opts.inlineConfigParser ?? 'yaml');
170
+ const basename = opts.inlineConfigParser === 'dockerfile' ? 'Dockerfile' : `config${ext}`;
171
+ // mkdtemp creates the directory atomically (O_CREAT|O_EXCL) -- safe temp file pattern.
172
+ const tmpDir = await mkdtemp(join(tmpdir(), 'orygn-conftest-'));
173
+ temps.push(tmpDir);
174
+ const configPath = join(tmpDir, basename);
175
+ await writeFile(configPath, opts.inlineConfig, 'utf8');
176
+ paths.configPath = configPath;
177
+ }
178
+ if (opts.inlinePolicy !== undefined) {
179
+ // mkdtemp creates the directory atomically (O_CREAT|O_EXCL) -- safe temp file pattern.
180
+ const policyDir = await mkdtemp(join(tmpdir(), 'orygn-conftest-policy-'));
181
+ temps.push(policyDir);
182
+ const policyFile = join(policyDir, 'policy.rego');
183
+ await writeFile(policyFile, opts.inlinePolicy, 'utf8');
184
+ paths.policyDir = policyDir;
185
+ }
186
+ return await fn(paths);
187
+ }
188
+ finally {
189
+ await Promise.all(temps.map((p) => rm(p, { recursive: true, force: true })));
190
+ }
191
+ }
192
+ /**
193
+ * Replace the temp inline-config path and temp inline-policy directory
194
+ * path in the stdout JSON with `<inline>` so callers never see
195
+ * implementation-internal temp paths.
196
+ *
197
+ * conftest emits paths inside a JSON array, so each backslash in the
198
+ * path is JSON-encoded as `\\`. We match the JSON-encoded form of the
199
+ * path to handle Windows paths correctly (forward slashes need no
200
+ * special treatment).
201
+ */
202
+ sanitizeOutput(result, configPath, policyDir) {
203
+ if (!configPath && !policyDir)
204
+ return result;
205
+ if (!result.stdout)
206
+ return result;
207
+ let stdout = result.stdout;
208
+ if (configPath) {
209
+ // JSON.stringify encodes backslashes as \\, so match the encoded form.
210
+ const jsonEncoded = JSON.stringify(configPath).slice(1, -1);
211
+ const escaped = jsonEncoded.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
212
+ stdout = stdout.replace(new RegExp(escaped, 'g'), '<inline>');
213
+ }
214
+ if (policyDir) {
215
+ const jsonEncoded = JSON.stringify(policyDir).slice(1, -1);
216
+ const escaped = jsonEncoded.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
217
+ // Policy dir appears in conftest output as part of file paths.
218
+ // Replace the full dir prefix so the policy filename is preserved.
219
+ stdout = stdout.replace(new RegExp(escaped, 'g'), '<inline-policy>');
220
+ }
221
+ return { ...result, stdout };
222
+ }
223
+ }
224
+ //# sourceMappingURL=conftest-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conftest-cli.js","sourceRoot":"","sources":["../../src/lib/conftest-cli.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,7 @@ import type { ToolEnvelope } from '../types.js';
30
30
  * subprocess exited normally (exitCode is a number) so the caller can
31
31
  * inspect the result.
32
32
  */
33
- export declare function mapSubprocessFailure(result: SpawnResult, binary: 'opa' | 'regal'): ToolEnvelope<never> | undefined;
33
+ export declare function mapSubprocessFailure(result: SpawnResult, binary: 'opa' | 'regal' | 'conftest'): ToolEnvelope<never> | undefined;
34
34
  /**
35
35
  * Try to parse `text` as JSON. Returns `undefined` on failure so the
36
36
  * caller can fall back to a textual error envelope rather than throwing.
@@ -1 +1 @@
1
- {"version":3,"file":"tool-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/tool-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAAqC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AACD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,KAAK,GAAG,OAAO,GACtB,YAAY,CAAC,KAAK,CAAC,GAAG,SAAS,CAwBjC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAOrE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACpC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;CAAE,CAU9E;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACnC,OAAO,CAAC,aAAa,CAAC,CASxB"}
1
+ {"version":3,"file":"tool-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/tool-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAAqC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AACD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,UAAU,GACnC,YAAY,CAAC,KAAK,CAAC,GAAG,SAAS,CA+BjC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAOrE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACpC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;CAAE,CAU9E;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACnC,OAAO,CAAC,aAAa,CAAC,CASxB"}
@@ -38,10 +38,16 @@ export function mapSubprocessFailure(result, binary) {
38
38
  });
39
39
  }
40
40
  if (result.exitCode === null) {
41
- const code = binary === 'opa' ? 'OPA_BINARY_NOT_FOUND' : 'REGAL_NOT_FOUND';
41
+ const code = binary === 'opa'
42
+ ? 'OPA_BINARY_NOT_FOUND'
43
+ : binary === 'regal'
44
+ ? 'REGAL_NOT_FOUND'
45
+ : 'CONFTEST_NOT_FOUND';
42
46
  const hint = binary === 'opa'
43
47
  ? 'Install OPA (https://www.openpolicyagent.org/docs/latest/) or set OPA_BINARY to the absolute path of the binary.'
44
- : 'Install Regal (https://docs.styra.com/regal) or set REGAL_BINARY to the absolute path of the binary.';
48
+ : binary === 'regal'
49
+ ? 'Install Regal (https://docs.styra.com/regal) or set REGAL_BINARY to the absolute path of the binary.'
50
+ : 'Install Conftest (https://www.conftest.dev/) or set CONFTEST_BINARY to the absolute path of the binary.';
45
51
  return err(code, `${binary} binary unreachable: ${result.stderr || 'spawn failed'}`, { hint });
46
52
  }
47
53
  if (result.timedOut) {
@@ -1 +1 @@
1
- {"version":3,"file":"tool-helpers.js","sourceRoot":"","sources":["../../src/lib/tool-helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-helpers.js","sourceRoot":"","sources":["../../src/lib/tool-helpers.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAYA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAI/E,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAQ7D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAuBrD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BvE;AAED;;;;;;;GAOG;AACH,wBAAsB,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAqBpE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAYA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAI/E,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAS7D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAuBrD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CvE;AAED;;;;;;;GAOG;AACH,wBAAsB,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAqBpE"}
package/dist/server.js CHANGED
@@ -15,6 +15,7 @@ import { formatHelp, formatStartupBanner, formatVersion, parseCliArgs } from './
15
15
  import { loadConfig } from './config.js';
16
16
  import { SERVER_NAME, SERVER_VERSION } from './constants.js';
17
17
  import { initLogger, logger } from './lib/logger.js';
18
+ import { ConftestCli } from './lib/conftest-cli.js';
18
19
  import { OpaCli } from './lib/opa-cli.js';
19
20
  import { RegalCli } from './lib/regal-cli.js';
20
21
  import { registerPrompts } from './prompts/index.js';
@@ -35,7 +36,7 @@ export function buildServer(config) {
35
36
  regalBinary: config.regalBinary,
36
37
  });
37
38
  const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, {
38
- instructions: '43 tools split into six categories. rego_* authoring/analysis tools use the local opa binary -- no running OPA server required. rego_lint requires regal (REGAL_BINARY). opa_* server-management tools talk to a live OPA instance via OPA_URL; set OPA_TOKEN if the server requires bearer-token authentication. File-based tools require paths inside OPA_MCP_ALLOWED_PATHS; inline-source tools work without it. Start with rego_check + rego_lint for policy authoring, mcp_server_info to confirm which binaries are reachable.',
39
+ instructions: '47 tools split into seven categories. rego_* authoring/analysis tools use the local opa binary -- no running OPA server required. rego_lint requires regal (REGAL_BINARY). opa_* server-management tools talk to a live OPA instance via OPA_URL; set OPA_TOKEN if the server requires bearer-token authentication. conftest_* tools use the local conftest binary (CONFTEST_BINARY) to test configuration files (Kubernetes manifests, Terraform plans, Dockerfiles) against Rego policies. File-based tools require paths inside OPA_MCP_ALLOWED_PATHS; inline-source tools work without it. Start with rego_check + rego_lint for policy authoring, conftest_test for configuration file validation, mcp_server_info to confirm which binaries are reachable.',
39
40
  });
40
41
  registerTools(server, config);
41
42
  registerPrompts(server, config);
@@ -56,9 +57,11 @@ export function buildServer(config) {
56
57
  export async function runStartupSelfCheck(config) {
57
58
  const opa = new OpaCli(config);
58
59
  const regal = new RegalCli(config);
59
- const [opaVersion, regalVersion] = await Promise.all([
60
+ const conftest = new ConftestCli(config);
61
+ const [opaVersion, regalVersion, conftestVersion] = await Promise.all([
60
62
  opa.version().catch(() => null),
61
63
  regal.version().catch(() => null),
64
+ conftest.version().catch(() => null),
62
65
  ]);
63
66
  if (opaVersion === null) {
64
67
  logger.warn('startup self-check: opa binary not reachable; rego_* tools will fail', {
@@ -78,6 +81,15 @@ export async function runStartupSelfCheck(config) {
78
81
  else {
79
82
  logger.info('startup self-check: regal OK', { version: regalVersion });
80
83
  }
84
+ if (conftestVersion === null) {
85
+ logger.warn('startup self-check: conftest binary not reachable; conftest_* tools will return CONFTEST_NOT_FOUND', {
86
+ conftestBinary: config.conftestBinary,
87
+ hint: 'set CONFTEST_BINARY to an absolute path, or ensure conftest is on PATH. Conftest is optional; only conftest_* tools require it.',
88
+ });
89
+ }
90
+ else {
91
+ logger.info('startup self-check: conftest OK', { version: conftestVersion });
92
+ }
81
93
  }
82
94
  /**
83
95
  * Entry-point flow: load config from env, build the server, connect
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Config } from '../../config.js';
3
+ export declare function registerConftestTools(server: McpServer, config: Config): void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/conftest/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAK7E"}
@@ -0,0 +1,11 @@
1
+ import { registerConftestPull } from './pull.js';
2
+ import { registerConftestPush } from './push.js';
3
+ import { registerConftestTest } from './test.js';
4
+ import { registerConftestVerify } from './verify.js';
5
+ export function registerConftestTools(server, config) {
6
+ registerConftestTest(server, config);
7
+ registerConftestVerify(server, config);
8
+ registerConftestPull(server, config);
9
+ registerConftestPush(server, config);
10
+ }
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/conftest/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,MAAc;IACrE,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Config } from '../../config.js';
3
+ export interface ConftestPullOutput {
4
+ /** The URL that was pulled. */
5
+ url: string;
6
+ /** The local directory where policies were written. */
7
+ policyDir: string;
8
+ }
9
+ export declare function registerConftestPull(server: McpServer, config: Config): void;
10
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/tools/conftest/pull.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA0B9C,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAsD5E"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * `conftest_pull` -- download Rego policies from an OCI registry or
3
+ * other remote source into a local directory.
4
+ *
5
+ * Teams that publish policy bundles to a registry (e.g. ghcr.io or
6
+ * Docker Hub) use `conftest pull` to hydrate the local `policy/`
7
+ * directory before running `conftest test`. This tool exposes that
8
+ * workflow so an LLM can fetch the latest policies and immediately
9
+ * evaluate config files against them.
10
+ *
11
+ * The URL format follows conftest's conventions:
12
+ * oci://ghcr.io/org/policies:tag
13
+ * github.com/open-policy-agent/conftest//examples/playkube/policy
14
+ *
15
+ * Exit code mapping:
16
+ * null -- binary not found → CONFTEST_NOT_FOUND
17
+ * 0 -- pull succeeded
18
+ * non-0 -- network / auth error
19
+ */
20
+ import { z } from 'zod';
21
+ import { ConftestCli } from '../../lib/conftest-cli.js';
22
+ import { err, ok } from '../../lib/errors.js';
23
+ import { mapSubprocessFailure, validatePaths, withToolEnvelope } from '../../lib/tool-helpers.js';
24
+ const ConftestPullInput = {
25
+ url: z
26
+ .string()
27
+ .min(1)
28
+ .describe('Policy URL to pull. Supported schemes: ' +
29
+ '`oci://registry/repo:tag` (OCI registry), ' +
30
+ '`github.com/org/repo//path` (GitHub subdirectory), ' +
31
+ '`git::https://example.com/repo//path` (generic Git). ' +
32
+ 'See https://www.conftest.dev/sharing/ for the full URL syntax.'),
33
+ policy: z
34
+ .string()
35
+ .optional()
36
+ .describe('Local directory where the pulled policies will be written. ' +
37
+ 'Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). ' +
38
+ "Defaults to `./policy` (conftest's convention)."),
39
+ };
40
+ export function registerConftestPull(server, config) {
41
+ const conftest = new ConftestCli(config);
42
+ server.registerTool('conftest_pull', {
43
+ title: 'Conftest pull',
44
+ description: 'Download Rego policies from an OCI registry or Git repository into a local directory ' +
45
+ 'using `conftest pull`. Use this to hydrate a local `policy/` directory before running ' +
46
+ '`conftest_test`. Requires `conftest` on PATH or `CONFTEST_BINARY` set. ' +
47
+ 'The `policy` directory must be inside OPA_MCP_ALLOWED_PATHS.',
48
+ inputSchema: ConftestPullInput,
49
+ annotations: {
50
+ readOnlyHint: false,
51
+ destructiveHint: true,
52
+ idempotentHint: true,
53
+ openWorldHint: true,
54
+ },
55
+ }, async (input, { signal }) => {
56
+ return withToolEnvelope(config, async () => {
57
+ // ── Path validation ──────────────────────────────────────────────
58
+ // The policy directory does not have to exist yet -- conftest will
59
+ // create it. Validate only that the parent is within allowed roots
60
+ // by validating the path itself (without mustExist).
61
+ if (input.policy !== undefined) {
62
+ const v = validatePaths([input.policy], config);
63
+ if (!v.ok)
64
+ return v.error;
65
+ input = { ...input, policy: v.resolved[0] };
66
+ }
67
+ // ── Run conftest pull ────────────────────────────────────────────
68
+ const result = await conftest.pull({ url: input.url, policy: input.policy }, signal);
69
+ const subprocessFailure = mapSubprocessFailure(result, 'conftest');
70
+ if (subprocessFailure)
71
+ return subprocessFailure;
72
+ if (result.exitCode === 0) {
73
+ return ok({
74
+ url: input.url,
75
+ policyDir: input.policy ?? 'policy',
76
+ });
77
+ }
78
+ const detail = result.stderr.trim() || result.stdout.trim();
79
+ return err('UNKNOWN_ERROR', `conftest pull failed with exit code ${result.exitCode}: ${detail}`, { details: { exitCode: result.exitCode, stderr: result.stderr.trim() } });
80
+ });
81
+ });
82
+ }
83
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../src/tools/conftest/pull.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Config } from '../../config.js';
3
+ export interface ConftestPushOutput {
4
+ /** The OCI repository the policies were pushed to. */
5
+ repository: string;
6
+ /** The local policy directory that was packaged and pushed. */
7
+ policyDir: string;
8
+ }
9
+ export declare function registerConftestPush(server: McpServer, config: Config): void;
10
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/tools/conftest/push.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAyB9C,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAuD5E"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * `conftest_push` -- publish a local Rego policy bundle to an OCI registry.
3
+ *
4
+ * Teams that centralize policies in a registry use `conftest push` to
5
+ * distribute them. The tool packages the local `policy/` directory as an
6
+ * OCI artifact and pushes it to the specified repository. Registry
7
+ * credentials are consumed from the host environment (docker login,
8
+ * ORAS keychain, REGISTRY_AUTH_FILE, etc.) -- they are never passed
9
+ * through the tool interface.
10
+ *
11
+ * Exit code mapping:
12
+ * null -- binary not found → CONFTEST_NOT_FOUND
13
+ * 0 -- push succeeded
14
+ * non-0 -- push error (auth failure, network error, etc.)
15
+ */
16
+ import { z } from 'zod';
17
+ import { ConftestCli } from '../../lib/conftest-cli.js';
18
+ import { err, ok } from '../../lib/errors.js';
19
+ import { mapSubprocessFailure, validatePaths, withToolEnvelope } from '../../lib/tool-helpers.js';
20
+ const ConftestPushInput = {
21
+ repository: z
22
+ .string()
23
+ .min(1)
24
+ .describe('OCI repository URL to push policies to (e.g. `ghcr.io/my-org/policies:latest`). ' +
25
+ 'Registry credentials must already be configured in the host environment ' +
26
+ '(via `docker login`, ORAS keychain, or REGISTRY_AUTH_FILE). ' +
27
+ 'This tool does not accept or store registry credentials.'),
28
+ policy: z
29
+ .string()
30
+ .optional()
31
+ .describe('Path to the local directory containing Rego policies to push. ' +
32
+ 'Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS) and must exist. ' +
33
+ "Defaults to `./policy` (conftest's convention)."),
34
+ };
35
+ export function registerConftestPush(server, config) {
36
+ const conftest = new ConftestCli(config);
37
+ server.registerTool('conftest_push', {
38
+ title: 'Conftest push',
39
+ description: 'Package the local Rego policy directory as an OCI artifact and push it to a registry ' +
40
+ 'using `conftest push`. Registry credentials must be pre-configured in the host ' +
41
+ 'environment (docker login, ORAS keychain, etc.) -- this tool never handles credentials. ' +
42
+ 'The `policy` directory must be inside OPA_MCP_ALLOWED_PATHS. ' +
43
+ 'Requires `conftest` on PATH or `CONFTEST_BINARY` set.',
44
+ inputSchema: ConftestPushInput,
45
+ annotations: {
46
+ readOnlyHint: false,
47
+ destructiveHint: true,
48
+ idempotentHint: false,
49
+ openWorldHint: true,
50
+ },
51
+ }, async (input, { signal }) => {
52
+ return withToolEnvelope(config, async () => {
53
+ // ── Path validation ──────────────────────────────────────────────
54
+ if (input.policy !== undefined) {
55
+ const v = validatePaths([input.policy], config, { mustExist: true });
56
+ if (!v.ok)
57
+ return v.error;
58
+ input = { ...input, policy: v.resolved[0] };
59
+ }
60
+ // ── Run conftest push ────────────────────────────────────────────
61
+ const result = await conftest.push({ repository: input.repository, policy: input.policy }, signal);
62
+ const subprocessFailure = mapSubprocessFailure(result, 'conftest');
63
+ if (subprocessFailure)
64
+ return subprocessFailure;
65
+ if (result.exitCode === 0) {
66
+ return ok({
67
+ repository: input.repository,
68
+ policyDir: input.policy ?? 'policy',
69
+ });
70
+ }
71
+ const detail = result.stderr.trim() || result.stdout.trim();
72
+ return err('UNKNOWN_ERROR', `conftest push failed with exit code ${result.exitCode}: ${detail}`, { details: { exitCode: result.exitCode, stderr: result.stderr.trim() } });
73
+ });
74
+ });
75
+ }
76
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../../src/tools/conftest/push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { Config } from '../../config.js';
3
+ import { type ConftestFileResult } from '../../lib/conftest-cli.js';
4
+ export interface ConftestTestOutput {
5
+ /** `true` when no failures (and no warnings if `failOnWarn` was set). */
6
+ passed: boolean;
7
+ /** Per-file, per-namespace evaluation results. */
8
+ results: ConftestFileResult[];
9
+ summary: {
10
+ /** Number of files with zero failures and zero warnings. */
11
+ passed: number;
12
+ /** Number of files with at least one failure. */
13
+ failed: number;
14
+ /** Total number of warning messages across all files. */
15
+ warnings: number;
16
+ /** Total number of skipped rules across all files. */
17
+ skipped: number;
18
+ };
19
+ }
20
+ export declare function registerConftestTest(server: McpServer, config: Config): void;
21
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/tools/conftest/test.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAiFjF,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,MAAM,EAAE,OAAO,CAAC;IAChB,kDAAkD;IAClD,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,OAAO,EAAE;QACP,4DAA4D;QAC5D,MAAM,EAAE,MAAM,CAAC;QACf,iDAAiD;QACjD,MAAM,EAAE,MAAM,CAAC;QACf,yDAAyD;QACzD,QAAQ,EAAE,MAAM,CAAC;QACjB,sDAAsD;QACtD,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA+G5E"}