@orygn/opa-mcp 0.1.9 → 0.1.11
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/CHANGELOG.md +69 -1
- package/README.md +55 -10
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/lib/conftest-cli.d.ts +144 -0
- package/dist/lib/conftest-cli.d.ts.map +1 -0
- package/dist/lib/conftest-cli.js +224 -0
- package/dist/lib/conftest-cli.js.map +1 -0
- package/dist/lib/tool-helpers.d.ts +1 -1
- package/dist/lib/tool-helpers.d.ts.map +1 -1
- package/dist/lib/tool-helpers.js +8 -2
- package/dist/lib/tool-helpers.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +14 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/authoring/check-schema.d.ts +20 -0
- package/dist/tools/authoring/check-schema.d.ts.map +1 -0
- package/dist/tools/authoring/check-schema.js +140 -0
- package/dist/tools/authoring/check-schema.js.map +1 -0
- package/dist/tools/authoring/index.d.ts.map +1 -1
- package/dist/tools/authoring/index.js +2 -0
- package/dist/tools/authoring/index.js.map +1 -1
- package/dist/tools/conftest/index.d.ts +4 -0
- package/dist/tools/conftest/index.d.ts.map +1 -0
- package/dist/tools/conftest/index.js +11 -0
- package/dist/tools/conftest/index.js.map +1 -0
- package/dist/tools/conftest/pull.d.ts +10 -0
- package/dist/tools/conftest/pull.d.ts.map +1 -0
- package/dist/tools/conftest/pull.js +83 -0
- package/dist/tools/conftest/pull.js.map +1 -0
- package/dist/tools/conftest/push.d.ts +10 -0
- package/dist/tools/conftest/push.d.ts.map +1 -0
- package/dist/tools/conftest/push.js +76 -0
- package/dist/tools/conftest/push.js.map +1 -0
- package/dist/tools/conftest/test.d.ts +21 -0
- package/dist/tools/conftest/test.d.ts.map +1 -0
- package/dist/tools/conftest/test.js +186 -0
- package/dist/tools/conftest/test.js.map +1 -0
- package/dist/tools/conftest/verify.d.ts +21 -0
- package/dist/tools/conftest/verify.d.ts.map +1 -0
- package/dist/tools/conftest/verify.js +112 -0
- package/dist/tools/conftest/verify.js.map +1 -0
- package/dist/tools/index.d.ts +13 -10
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `conftest_test` -- evaluate configuration files against Rego policies
|
|
3
|
+
* using the `conftest test` command.
|
|
4
|
+
*
|
|
5
|
+
* Conftest is the standard CLI for policy-as-code testing of Kubernetes
|
|
6
|
+
* manifests, Terraform plans, Dockerfiles, Helm charts, and any other
|
|
7
|
+
* structured configuration. This tool surfaces pass/fail/warn results
|
|
8
|
+
* per file and per namespace so an LLM can explain exactly which policies
|
|
9
|
+
* fired and why.
|
|
10
|
+
*
|
|
11
|
+
* Exit code mapping:
|
|
12
|
+
* null -- conftest binary not found → CONFTEST_NOT_FOUND
|
|
13
|
+
* 0 -- all tests pass (ok: true, passed: true)
|
|
14
|
+
* 1 -- one or more failures (ok: true, passed: false)
|
|
15
|
+
* 2+ -- command error (bad args, policy not found, etc.)
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import { ConftestCli } from '../../lib/conftest-cli.js';
|
|
19
|
+
import { err, ok } from '../../lib/errors.js';
|
|
20
|
+
import { mapSubprocessFailure, tryParseJson, validatePaths, withToolEnvelope, } from '../../lib/tool-helpers.js';
|
|
21
|
+
const ConftestTestInput = {
|
|
22
|
+
files: z
|
|
23
|
+
.array(z.string())
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('Filesystem paths to configuration files to evaluate (YAML, JSON, HCL, Dockerfile, etc.). ' +
|
|
26
|
+
'Each path must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). ' +
|
|
27
|
+
'Mutually exclusive with `inlineConfig`.'),
|
|
28
|
+
inlineConfig: z
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Inline configuration content to evaluate (e.g. a Kubernetes manifest as a YAML string). ' +
|
|
32
|
+
'Mutually exclusive with `files`. Defaults to YAML format; set `inlineConfigParser` to override.'),
|
|
33
|
+
inlineConfigParser: z
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe('Parser to use for `inlineConfig`. Valid values: yaml (default), json, toml, hcl1, hcl2, ' +
|
|
37
|
+
'ini, xml, dotenv, cue, jsonnet, properties, dockerfile. ' +
|
|
38
|
+
"Ignored when `files` is used (conftest infers the parser from each file's extension)."),
|
|
39
|
+
policy: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Path to a directory or file containing Rego policies. ' +
|
|
43
|
+
'Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). ' +
|
|
44
|
+
'Mutually exclusive with `inlinePolicy`. ' +
|
|
45
|
+
'Omit to let conftest use its default `./policy` directory.'),
|
|
46
|
+
inlinePolicy: z
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Inline Rego policy source. Written to a temporary directory and passed as `--policy`. ' +
|
|
50
|
+
'The policy should declare `package main` (or match the `namespace` parameter). ' +
|
|
51
|
+
'Mutually exclusive with `policy`.'),
|
|
52
|
+
namespace: z
|
|
53
|
+
.string()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe('Rego namespace (package name) to test against. Defaults to `main`. ' +
|
|
56
|
+
'Use `allNamespaces: true` to test all discovered namespaces instead.'),
|
|
57
|
+
allNamespaces: z
|
|
58
|
+
.boolean()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Test policies found in all discovered namespaces. Overrides `namespace`.'),
|
|
61
|
+
data: z
|
|
62
|
+
.array(z.string())
|
|
63
|
+
.optional()
|
|
64
|
+
.describe('Paths to directories from which additional data will be loaded for the Rego policies. ' +
|
|
65
|
+
'Each path must be inside an allowed root.'),
|
|
66
|
+
combine: z
|
|
67
|
+
.boolean()
|
|
68
|
+
.optional()
|
|
69
|
+
.describe('Combine all configuration files into a single input document before evaluating. ' +
|
|
70
|
+
'Useful when policies need to inspect relationships across multiple files.'),
|
|
71
|
+
failOnWarn: z
|
|
72
|
+
.boolean()
|
|
73
|
+
.optional()
|
|
74
|
+
.describe('Return `passed: false` even when only warnings (no hard failures) are present.'),
|
|
75
|
+
};
|
|
76
|
+
export function registerConftestTest(server, config) {
|
|
77
|
+
const conftest = new ConftestCli(config);
|
|
78
|
+
server.registerTool('conftest_test', {
|
|
79
|
+
title: 'Conftest test',
|
|
80
|
+
description: 'Evaluate configuration files (Kubernetes manifests, Terraform plans, Dockerfiles, Helm ' +
|
|
81
|
+
'charts, or any YAML/JSON/HCL/TOML/INI) against Rego policies using `conftest test`. ' +
|
|
82
|
+
'Returns per-file, per-namespace pass/fail/warn results so you can pinpoint exactly which ' +
|
|
83
|
+
'policy rules fired. Requires `conftest` on PATH or `CONFTEST_BINARY` set; returns ' +
|
|
84
|
+
'CONFTEST_NOT_FOUND otherwise. ' +
|
|
85
|
+
'Provide config via `files` (disk paths) or `inlineConfig` (inline string). ' +
|
|
86
|
+
'Provide policy via `policy` (disk path) or `inlinePolicy` (inline Rego source). ' +
|
|
87
|
+
"Omit `policy` and `inlinePolicy` to use conftest's default `./policy` directory.",
|
|
88
|
+
inputSchema: ConftestTestInput,
|
|
89
|
+
annotations: {
|
|
90
|
+
readOnlyHint: true,
|
|
91
|
+
destructiveHint: false,
|
|
92
|
+
idempotentHint: true,
|
|
93
|
+
openWorldHint: false,
|
|
94
|
+
},
|
|
95
|
+
}, async (input, { signal }) => {
|
|
96
|
+
return withToolEnvelope(config, async () => {
|
|
97
|
+
// ── Mutual exclusion checks ──────────────────────────────────────
|
|
98
|
+
if (input.files?.length && input.inlineConfig !== undefined) {
|
|
99
|
+
return err('INVALID_INPUT', '`files` and `inlineConfig` are mutually exclusive.');
|
|
100
|
+
}
|
|
101
|
+
if (!input.files?.length && input.inlineConfig === undefined) {
|
|
102
|
+
return err('INVALID_INPUT', 'Provide either `files` (array of config file paths) or `inlineConfig` (inline config string).');
|
|
103
|
+
}
|
|
104
|
+
if (input.policy !== undefined && input.inlinePolicy !== undefined) {
|
|
105
|
+
return err('INVALID_INPUT', '`policy` and `inlinePolicy` are mutually exclusive.');
|
|
106
|
+
}
|
|
107
|
+
// ── Path validation ──────────────────────────────────────────────
|
|
108
|
+
if (input.files?.length) {
|
|
109
|
+
const v = validatePaths(input.files, config, { mustExist: true });
|
|
110
|
+
if (!v.ok)
|
|
111
|
+
return v.error;
|
|
112
|
+
input = { ...input, files: v.resolved };
|
|
113
|
+
}
|
|
114
|
+
if (input.policy !== undefined) {
|
|
115
|
+
const v = validatePaths([input.policy], config, { mustExist: true });
|
|
116
|
+
if (!v.ok)
|
|
117
|
+
return v.error;
|
|
118
|
+
input = { ...input, policy: v.resolved[0] };
|
|
119
|
+
}
|
|
120
|
+
if (input.data?.length) {
|
|
121
|
+
const v = validatePaths(input.data, config, { mustExist: true });
|
|
122
|
+
if (!v.ok)
|
|
123
|
+
return v.error;
|
|
124
|
+
input = { ...input, data: v.resolved };
|
|
125
|
+
}
|
|
126
|
+
// ── Run conftest ─────────────────────────────────────────────────
|
|
127
|
+
const result = await conftest.test({
|
|
128
|
+
files: input.files,
|
|
129
|
+
inlineConfig: input.inlineConfig,
|
|
130
|
+
inlineConfigParser: input.inlineConfigParser,
|
|
131
|
+
policy: input.policy,
|
|
132
|
+
inlinePolicy: input.inlinePolicy,
|
|
133
|
+
namespace: input.namespace,
|
|
134
|
+
allNamespaces: input.allNamespaces,
|
|
135
|
+
data: input.data,
|
|
136
|
+
combine: input.combine,
|
|
137
|
+
failOnWarn: input.failOnWarn,
|
|
138
|
+
}, signal);
|
|
139
|
+
// ── Map universal subprocess failures ────────────────────────────
|
|
140
|
+
const subprocessFailure = mapSubprocessFailure(result, 'conftest');
|
|
141
|
+
if (subprocessFailure)
|
|
142
|
+
return subprocessFailure;
|
|
143
|
+
// ── Exit code 0 / 1: parse JSON results ─────────────────────────
|
|
144
|
+
// Exit 0 = all pass, exit 1 = failures present.
|
|
145
|
+
// Both produce valid JSON on stdout.
|
|
146
|
+
if (result.exitCode === 0 || result.exitCode === 1) {
|
|
147
|
+
const parsed = tryParseJson(result.stdout);
|
|
148
|
+
if (!parsed || !Array.isArray(parsed)) {
|
|
149
|
+
return err('UNKNOWN_ERROR', 'conftest test produced no parseable JSON output.', {
|
|
150
|
+
details: { stderr: result.stderr.trim(), exitCode: result.exitCode },
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const summary = buildSummary(parsed);
|
|
154
|
+
return ok({
|
|
155
|
+
passed: result.exitCode === 0,
|
|
156
|
+
results: parsed,
|
|
157
|
+
summary,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// ── Exit code 2+: command-level error ────────────────────────────
|
|
161
|
+
// Examples: policy directory not found, malformed Rego syntax,
|
|
162
|
+
// unknown --parser value, etc.
|
|
163
|
+
const detail = result.stderr.trim() || result.stdout.trim();
|
|
164
|
+
return err('UNKNOWN_ERROR', `conftest test failed with exit code ${result.exitCode}: ${detail}`, { details: { exitCode: result.exitCode, stderr: result.stderr.trim() } });
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
169
|
+
function buildSummary(results) {
|
|
170
|
+
let passed = 0;
|
|
171
|
+
let failed = 0;
|
|
172
|
+
let warnings = 0;
|
|
173
|
+
let skipped = 0;
|
|
174
|
+
for (const r of results) {
|
|
175
|
+
if (r.failures.length > 0) {
|
|
176
|
+
failed++;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
passed++;
|
|
180
|
+
}
|
|
181
|
+
warnings += r.warnings.length;
|
|
182
|
+
skipped += r.skipped.length;
|
|
183
|
+
}
|
|
184
|
+
return { passed, failed, warnings, skipped };
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/tools/conftest/test.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 ConftestVerifyOutput {
|
|
5
|
+
/** `true` when all `test_*` rules in all test files pass. */
|
|
6
|
+
passed: boolean;
|
|
7
|
+
/** Per-test-file results. */
|
|
8
|
+
results: ConftestFileResult[];
|
|
9
|
+
summary: {
|
|
10
|
+
/** Number of test files with zero failures. */
|
|
11
|
+
passed: number;
|
|
12
|
+
/** Number of test files with at least one failure. */
|
|
13
|
+
failed: number;
|
|
14
|
+
/** Total test cases that passed (sum of `successes` across all files). */
|
|
15
|
+
totalPassed: number;
|
|
16
|
+
/** Total test cases that failed (sum of `failures` across all files). */
|
|
17
|
+
totalFailed: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function registerConftestVerify(server: McpServer, config: Config): void;
|
|
21
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/tools/conftest/verify.ts"],"names":[],"mappings":"AAiBA,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;AA8BjF,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,6BAA6B;IAC7B,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,OAAO,EAAE;QACP,+CAA+C;QAC/C,MAAM,EAAE,MAAM,CAAC;QACf,sDAAsD;QACtD,MAAM,EAAE,MAAM,CAAC;QACf,0EAA0E;QAC1E,WAAW,EAAE,MAAM,CAAC;QACpB,yEAAyE;QACzE,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAyE9E"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `conftest_verify` -- run the `_test.rego` unit tests that live inside
|
|
3
|
+
* a conftest policy directory.
|
|
4
|
+
*
|
|
5
|
+
* Conftest verify is conftest's equivalent of `opa test`: it evaluates
|
|
6
|
+
* rules whose names begin with `test_` inside `*_test.rego` files within
|
|
7
|
+
* the policy directory. Use this to confirm that the policies themselves
|
|
8
|
+
* are correct before deploying them.
|
|
9
|
+
*
|
|
10
|
+
* Exit code mapping (same as conftest_test):
|
|
11
|
+
* null -- binary not found → CONFTEST_NOT_FOUND
|
|
12
|
+
* 0 -- all tests pass
|
|
13
|
+
* 1 -- one or more test failures
|
|
14
|
+
* 2+ -- command error
|
|
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, tryParseJson, validatePaths, withToolEnvelope, } from '../../lib/tool-helpers.js';
|
|
20
|
+
const ConftestVerifyInput = {
|
|
21
|
+
policy: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('Path to the directory containing both the Rego policies and the `*_test.rego` test files. ' +
|
|
25
|
+
'Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). ' +
|
|
26
|
+
"Omit to use conftest's default `./policy` directory."),
|
|
27
|
+
namespace: z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('Namespace to verify. Defaults to `main`. Omit to verify all namespaces.'),
|
|
31
|
+
data: z
|
|
32
|
+
.array(z.string())
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('Paths to data directories. Each must be inside an allowed root (OPA_MCP_ALLOWED_PATHS).'),
|
|
35
|
+
};
|
|
36
|
+
export function registerConftestVerify(server, config) {
|
|
37
|
+
const conftest = new ConftestCli(config);
|
|
38
|
+
server.registerTool('conftest_verify', {
|
|
39
|
+
title: 'Conftest verify',
|
|
40
|
+
description: 'Run the `test_*` rules inside `*_test.rego` files within a conftest policy directory, ' +
|
|
41
|
+
'verifying that the policies themselves are correct. Equivalent to `opa test` but using ' +
|
|
42
|
+
"conftest's policy-loading machinery. Returns per-file pass/fail results. " +
|
|
43
|
+
'Requires `conftest` on PATH or `CONFTEST_BINARY` set; returns CONFTEST_NOT_FOUND otherwise.',
|
|
44
|
+
inputSchema: ConftestVerifyInput,
|
|
45
|
+
annotations: {
|
|
46
|
+
readOnlyHint: true,
|
|
47
|
+
destructiveHint: false,
|
|
48
|
+
idempotentHint: true,
|
|
49
|
+
openWorldHint: false,
|
|
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
|
+
if (input.data?.length) {
|
|
61
|
+
const v = validatePaths(input.data, config, { mustExist: true });
|
|
62
|
+
if (!v.ok)
|
|
63
|
+
return v.error;
|
|
64
|
+
input = { ...input, data: v.resolved };
|
|
65
|
+
}
|
|
66
|
+
// ── Run conftest verify ──────────────────────────────────────────
|
|
67
|
+
const result = await conftest.verify({
|
|
68
|
+
policy: input.policy,
|
|
69
|
+
namespace: input.namespace,
|
|
70
|
+
data: input.data,
|
|
71
|
+
}, signal);
|
|
72
|
+
const subprocessFailure = mapSubprocessFailure(result, 'conftest');
|
|
73
|
+
if (subprocessFailure)
|
|
74
|
+
return subprocessFailure;
|
|
75
|
+
if (result.exitCode === 0 || result.exitCode === 1) {
|
|
76
|
+
const parsed = tryParseJson(result.stdout);
|
|
77
|
+
if (!parsed || !Array.isArray(parsed)) {
|
|
78
|
+
return err('UNKNOWN_ERROR', 'conftest verify produced no parseable JSON output.', {
|
|
79
|
+
details: { stderr: result.stderr.trim(), exitCode: result.exitCode },
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const summary = buildVerifySummary(parsed);
|
|
83
|
+
return ok({
|
|
84
|
+
passed: result.exitCode === 0,
|
|
85
|
+
results: parsed,
|
|
86
|
+
summary,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const detail = result.stderr.trim() || result.stdout.trim();
|
|
90
|
+
return err('UNKNOWN_ERROR', `conftest verify failed with exit code ${result.exitCode}: ${detail}`, { details: { exitCode: result.exitCode, stderr: result.stderr.trim() } });
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
95
|
+
function buildVerifySummary(results) {
|
|
96
|
+
let passed = 0;
|
|
97
|
+
let failed = 0;
|
|
98
|
+
let totalPassed = 0;
|
|
99
|
+
let totalFailed = 0;
|
|
100
|
+
for (const r of results) {
|
|
101
|
+
if (r.failures.length > 0) {
|
|
102
|
+
failed++;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
passed++;
|
|
106
|
+
}
|
|
107
|
+
totalPassed += r.successes;
|
|
108
|
+
totalFailed += r.failures.length;
|
|
109
|
+
}
|
|
110
|
+
return { passed, failed, totalPassed, totalFailed };
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/tools/conftest/verify.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -5,21 +5,23 @@
|
|
|
5
5
|
* here in order; ordering doesn't affect behavior but keeps the
|
|
6
6
|
* declaration site tidy.
|
|
7
7
|
*
|
|
8
|
-
* Tools
|
|
9
|
-
* Category A -- Authoring: rego_format, rego_check,
|
|
8
|
+
* Tools (48 total):
|
|
9
|
+
* Category A -- Authoring: rego_format, rego_check,
|
|
10
|
+
* rego_check_schema, rego_lint,
|
|
10
11
|
* rego_parse_ast, rego_inspect,
|
|
11
12
|
* rego_capabilities, rego_deps
|
|
12
13
|
* Category B -- Evaluation: rego_eval, rego_eval_with_explain,
|
|
13
14
|
* rego_eval_with_profile,
|
|
14
15
|
* rego_eval_with_coverage, rego_test,
|
|
15
16
|
* rego_bench, rego_compile_query
|
|
16
|
-
* Category C -- Bundles: opa_bundle_build, opa_bundle_sign
|
|
17
|
+
* Category C -- Bundles: opa_bundle_build, opa_bundle_sign,
|
|
18
|
+
* opa_bundle_verify, opa_exec
|
|
17
19
|
* Category D -- Server mgmt: opa_list_policies, opa_get_policy,
|
|
18
20
|
* opa_put_policy, opa_delete_policy,
|
|
19
21
|
* opa_get_data, opa_put_data,
|
|
20
|
-
* opa_patch_data,
|
|
21
|
-
*
|
|
22
|
-
* opa_status, opa_config
|
|
22
|
+
* opa_patch_data, opa_delete_data,
|
|
23
|
+
* opa_query_decision, opa_compile_query,
|
|
24
|
+
* opa_health, opa_status, opa_config
|
|
23
25
|
* Category E -- Helpers: rego_explain_decision,
|
|
24
26
|
* rego_generate_test_skeleton,
|
|
25
27
|
* rego_describe_policy,
|
|
@@ -27,10 +29,11 @@
|
|
|
27
29
|
* rego_coverage_gaps,
|
|
28
30
|
* rego_security_audit,
|
|
29
31
|
* rego_infer_input_schema,
|
|
30
|
-
* rego_fix,
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* rego_fix, rego_format_write,
|
|
33
|
+
* rego_migrate_v1, rego_policy_diff
|
|
34
|
+
* Category F -- Conftest: conftest_test, conftest_verify,
|
|
35
|
+
* conftest_pull, conftest_push
|
|
36
|
+
* Category G -- Meta: mcp_server_info
|
|
34
37
|
*/
|
|
35
38
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
36
39
|
import type { Config } from '../config.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAS3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQrE"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerAuthoringTools } from './authoring/index.js';
|
|
2
2
|
import { registerBundleTools } from './bundles/index.js';
|
|
3
|
+
import { registerConftestTools } from './conftest/index.js';
|
|
3
4
|
import { registerEvaluationTools } from './evaluation/index.js';
|
|
4
5
|
import { registerHelperTools } from './helpers/index.js';
|
|
5
6
|
import { registerMetaTools } from './meta/index.js';
|
|
@@ -10,6 +11,7 @@ export function registerTools(server, config) {
|
|
|
10
11
|
registerBundleTools(server, config);
|
|
11
12
|
registerServerManagementTools(server, config);
|
|
12
13
|
registerHelperTools(server, config);
|
|
14
|
+
registerConftestTools(server, config);
|
|
13
15
|
registerMetaTools(server, config);
|
|
14
16
|
}
|
|
15
17
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAwCA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAE7E,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,MAAc;IAC7D,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,6BAA6B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC"}
|