@orygn/opa-mcp 0.0.0 → 0.1.1
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 +150 -0
- package/LICENSE +21 -0
- package/README.md +622 -2
- package/dist/config.d.ts +58 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +72 -0
- package/dist/config.js.map +1 -0
- package/dist/lib/errors.d.ts +18 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +25 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/logger.d.ts +10 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +57 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/opa-cli.d.ts +226 -0
- package/dist/lib/opa-cli.d.ts.map +1 -0
- package/dist/lib/opa-cli.js +283 -0
- package/dist/lib/opa-cli.js.map +1 -0
- package/dist/lib/opa-client.d.ts +47 -0
- package/dist/lib/opa-client.d.ts.map +1 -0
- package/dist/lib/opa-client.js +101 -0
- package/dist/lib/opa-client.js.map +1 -0
- package/dist/lib/output.d.ts +17 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +21 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/regal-cli.d.ts +79 -0
- package/dist/lib/regal-cli.d.ts.map +1 -0
- package/dist/lib/regal-cli.js +122 -0
- package/dist/lib/regal-cli.js.map +1 -0
- package/dist/lib/security.d.ts +16 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +64 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/subprocess.d.ts +26 -0
- package/dist/lib/subprocess.d.ts.map +1 -0
- package/dist/lib/subprocess.js +72 -0
- package/dist/lib/subprocess.js.map +1 -0
- package/dist/lib/tool-helpers.d.ts +46 -0
- package/dist/lib/tool-helpers.d.ts.map +1 -0
- package/dist/lib/tool-helpers.js +73 -0
- package/dist/lib/tool-helpers.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +147 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/index.d.ts +12 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +107 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/patterns.d.ts +9 -0
- package/dist/resources/patterns.d.ts.map +1 -0
- package/dist/resources/patterns.js +375 -0
- package/dist/resources/patterns.js.map +1 -0
- package/dist/resources/style-guide.d.ts +6 -0
- package/dist/resources/style-guide.d.ts.map +1 -0
- package/dist/resources/style-guide.js +187 -0
- package/dist/resources/style-guide.js.map +1 -0
- package/dist/server.d.ts +34 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +125 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/authoring/capabilities.d.ts +11 -0
- package/dist/tools/authoring/capabilities.d.ts.map +1 -0
- package/dist/tools/authoring/capabilities.js +57 -0
- package/dist/tools/authoring/capabilities.js.map +1 -0
- package/dist/tools/authoring/check.d.ts +18 -0
- package/dist/tools/authoring/check.d.ts.map +1 -0
- package/dist/tools/authoring/check.js +71 -0
- package/dist/tools/authoring/check.js.map +1 -0
- package/dist/tools/authoring/deps.d.ts +8 -0
- package/dist/tools/authoring/deps.d.ts.map +1 -0
- package/dist/tools/authoring/deps.js +51 -0
- package/dist/tools/authoring/deps.js.map +1 -0
- package/dist/tools/authoring/format.d.ts +8 -0
- package/dist/tools/authoring/format.d.ts.map +1 -0
- package/dist/tools/authoring/format.js +44 -0
- package/dist/tools/authoring/format.js.map +1 -0
- package/dist/tools/authoring/index.d.ts +11 -0
- package/dist/tools/authoring/index.d.ts.map +1 -0
- package/dist/tools/authoring/index.js +17 -0
- package/dist/tools/authoring/index.js.map +1 -0
- package/dist/tools/authoring/inspect.d.ts +10 -0
- package/dist/tools/authoring/inspect.d.ts.map +1 -0
- package/dist/tools/authoring/inspect.js +47 -0
- package/dist/tools/authoring/inspect.js.map +1 -0
- package/dist/tools/authoring/lint.d.ts +18 -0
- package/dist/tools/authoring/lint.d.ts.map +1 -0
- package/dist/tools/authoring/lint.js +111 -0
- package/dist/tools/authoring/lint.js.map +1 -0
- package/dist/tools/authoring/parse.d.ts +7 -0
- package/dist/tools/authoring/parse.d.ts.map +1 -0
- package/dist/tools/authoring/parse.js +43 -0
- package/dist/tools/authoring/parse.js.map +1 -0
- package/dist/tools/bundles/build.d.ts +8 -0
- package/dist/tools/bundles/build.d.ts.map +1 -0
- package/dist/tools/bundles/build.js +87 -0
- package/dist/tools/bundles/build.js.map +1 -0
- package/dist/tools/bundles/index.d.ts +10 -0
- package/dist/tools/bundles/index.d.ts.map +1 -0
- package/dist/tools/bundles/index.js +7 -0
- package/dist/tools/bundles/index.js.map +1 -0
- package/dist/tools/bundles/sign.d.ts +8 -0
- package/dist/tools/bundles/sign.d.ts.map +1 -0
- package/dist/tools/bundles/sign.js +47 -0
- package/dist/tools/bundles/sign.js.map +1 -0
- package/dist/tools/evaluation/_shared.d.ts +55 -0
- package/dist/tools/evaluation/_shared.d.ts.map +1 -0
- package/dist/tools/evaluation/_shared.js +102 -0
- package/dist/tools/evaluation/_shared.js.map +1 -0
- package/dist/tools/evaluation/bench.d.ts +9 -0
- package/dist/tools/evaluation/bench.d.ts.map +1 -0
- package/dist/tools/evaluation/bench.js +76 -0
- package/dist/tools/evaluation/bench.js.map +1 -0
- package/dist/tools/evaluation/compile.d.ts +11 -0
- package/dist/tools/evaluation/compile.d.ts.map +1 -0
- package/dist/tools/evaluation/compile.js +19 -0
- package/dist/tools/evaluation/compile.js.map +1 -0
- package/dist/tools/evaluation/eval.d.ts +10 -0
- package/dist/tools/evaluation/eval.d.ts.map +1 -0
- package/dist/tools/evaluation/eval.js +35 -0
- package/dist/tools/evaluation/eval.js.map +1 -0
- package/dist/tools/evaluation/index.d.ts +11 -0
- package/dist/tools/evaluation/index.d.ts.map +1 -0
- package/dist/tools/evaluation/index.js +11 -0
- package/dist/tools/evaluation/index.js.map +1 -0
- package/dist/tools/evaluation/test.d.ts +28 -0
- package/dist/tools/evaluation/test.d.ts.map +1 -0
- package/dist/tools/evaluation/test.js +74 -0
- package/dist/tools/evaluation/test.js.map +1 -0
- package/dist/tools/helpers/describe-policy.d.ts +26 -0
- package/dist/tools/helpers/describe-policy.d.ts.map +1 -0
- package/dist/tools/helpers/describe-policy.js +76 -0
- package/dist/tools/helpers/describe-policy.js.map +1 -0
- package/dist/tools/helpers/explain-decision.d.ts +41 -0
- package/dist/tools/helpers/explain-decision.d.ts.map +1 -0
- package/dist/tools/helpers/explain-decision.js +75 -0
- package/dist/tools/helpers/explain-decision.js.map +1 -0
- package/dist/tools/helpers/generate-test-skeleton.d.ts +8 -0
- package/dist/tools/helpers/generate-test-skeleton.d.ts.map +1 -0
- package/dist/tools/helpers/generate-test-skeleton.js +93 -0
- package/dist/tools/helpers/generate-test-skeleton.js.map +1 -0
- package/dist/tools/helpers/index.d.ts +12 -0
- package/dist/tools/helpers/index.d.ts.map +1 -0
- package/dist/tools/helpers/index.js +11 -0
- package/dist/tools/helpers/index.js.map +1 -0
- package/dist/tools/helpers/suggest-fix.d.ts +15 -0
- package/dist/tools/helpers/suggest-fix.d.ts.map +1 -0
- package/dist/tools/helpers/suggest-fix.js +119 -0
- package/dist/tools/helpers/suggest-fix.js.map +1 -0
- package/dist/tools/index.d.ts +31 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/server-management/_shared.d.ts +9 -0
- package/dist/tools/server-management/_shared.d.ts.map +1 -0
- package/dist/tools/server-management/_shared.js +41 -0
- package/dist/tools/server-management/_shared.js.map +1 -0
- package/dist/tools/server-management/data.d.ts +4 -0
- package/dist/tools/server-management/data.d.ts.map +1 -0
- package/dist/tools/server-management/data.js +90 -0
- package/dist/tools/server-management/data.js.map +1 -0
- package/dist/tools/server-management/decisions.d.ts +4 -0
- package/dist/tools/server-management/decisions.d.ts.map +1 -0
- package/dist/tools/server-management/decisions.js +87 -0
- package/dist/tools/server-management/decisions.js.map +1 -0
- package/dist/tools/server-management/index.d.ts +11 -0
- package/dist/tools/server-management/index.d.ts.map +1 -0
- package/dist/tools/server-management/index.js +11 -0
- package/dist/tools/server-management/index.js.map +1 -0
- package/dist/tools/server-management/policies.d.ts +4 -0
- package/dist/tools/server-management/policies.d.ts.map +1 -0
- package/dist/tools/server-management/policies.js +94 -0
- package/dist/tools/server-management/policies.js.map +1 -0
- package/dist/tools/server-management/status.d.ts +4 -0
- package/dist/tools/server-management/status.d.ts.map +1 -0
- package/dist/tools/server-management/status.js +82 -0
- package/dist/tools/server-management/status.js.map +1 -0
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +86 -4
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper around the optional `regal` binary (Rego linter, by Styra).
|
|
3
|
+
*
|
|
4
|
+
* Regal is OPTIONAL — only the `rego_lint` tool requires it. Other
|
|
5
|
+
* tools work without Regal installed. If absent, `rego_lint` returns a
|
|
6
|
+
* structured `REGAL_NOT_FOUND` error with an install hint.
|
|
7
|
+
*/
|
|
8
|
+
import { randomUUID } from 'node:crypto';
|
|
9
|
+
import { rm, writeFile } from 'node:fs/promises';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { runBinary } from './subprocess.js';
|
|
13
|
+
/**
|
|
14
|
+
* Rules whose verdict depends on the on-disk path of the file being
|
|
15
|
+
* linted. When a caller passes inline `source`, the file lives at a
|
|
16
|
+
* randomized temp path that can never match the source's declared
|
|
17
|
+
* package, so these rules always fire as false positives. Auto-disabled
|
|
18
|
+
* for inline source unless the caller explicitly re-enables them.
|
|
19
|
+
*/
|
|
20
|
+
export const INLINE_SOURCE_FALSE_POSITIVE_RULES = ['directory-package-mismatch'];
|
|
21
|
+
/**
|
|
22
|
+
* Wrapper around the local `regal` binary.
|
|
23
|
+
*
|
|
24
|
+
* Like `OpaCli`, methods do not throw on Regal-side errors — the exit
|
|
25
|
+
* code on the returned `SpawnResult` is the signal. Inline source is
|
|
26
|
+
* always written to a temp file because `regal lint` does not read
|
|
27
|
+
* from stdin.
|
|
28
|
+
*/
|
|
29
|
+
export class RegalCli {
|
|
30
|
+
config;
|
|
31
|
+
constructor(config) {
|
|
32
|
+
this.config = config;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Verify the binary is present and report its version. Returns null
|
|
36
|
+
* if the binary is unreachable or output is malformed.
|
|
37
|
+
*/
|
|
38
|
+
async version() {
|
|
39
|
+
const result = await this.run(['version']);
|
|
40
|
+
if (result.exitCode !== 0)
|
|
41
|
+
return null;
|
|
42
|
+
const match = /Version:\s*(\S+)/i.exec(result.stdout) ?? /v?(\d+\.\d+\.\d+\S*)/i.exec(result.stdout);
|
|
43
|
+
return match?.[1] ?? null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Lint Rego source. Stdout is JSON when `--format=json` is set
|
|
47
|
+
* (always, here). Either `source` or one or more `paths` must be
|
|
48
|
+
* provided.
|
|
49
|
+
*
|
|
50
|
+
* Regal's exit codes:
|
|
51
|
+
* - 0 — no findings at or above `failLevel`
|
|
52
|
+
* - 3 — findings present
|
|
53
|
+
* - non-zero other — Regal-internal failure (config error, etc.)
|
|
54
|
+
*
|
|
55
|
+
* When called with inline `source`, location-bound rules whose
|
|
56
|
+
* verdict depends on the on-disk path (currently
|
|
57
|
+
* `directory-package-mismatch`) are auto-disabled because the
|
|
58
|
+
* randomized temp-file path makes those rules false positives.
|
|
59
|
+
* Callers that want them anyway can re-enable via `enable`.
|
|
60
|
+
*/
|
|
61
|
+
async lint(input) {
|
|
62
|
+
if (!input.source && !input.paths?.length) {
|
|
63
|
+
throw new Error('regal lint requires either source or at least one path');
|
|
64
|
+
}
|
|
65
|
+
const args = ['lint', '--format=json', '--no-color'];
|
|
66
|
+
if (input.configFile)
|
|
67
|
+
args.push('--config-file', input.configFile);
|
|
68
|
+
if (input.failLevel)
|
|
69
|
+
args.push('--fail-level', input.failLevel);
|
|
70
|
+
if (input.disableAll)
|
|
71
|
+
args.push('--disable-all');
|
|
72
|
+
if (input.enableAll)
|
|
73
|
+
args.push('--enable-all');
|
|
74
|
+
const userEnable = new Set(input.enable ?? []);
|
|
75
|
+
const userDisable = new Set(input.disable ?? []);
|
|
76
|
+
const effectiveDisable = new Set(userDisable);
|
|
77
|
+
if (input.source !== undefined) {
|
|
78
|
+
for (const rule of INLINE_SOURCE_FALSE_POSITIVE_RULES) {
|
|
79
|
+
if (!userEnable.has(rule))
|
|
80
|
+
effectiveDisable.add(rule);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const rule of effectiveDisable)
|
|
84
|
+
args.push('--disable', rule);
|
|
85
|
+
for (const rule of userEnable)
|
|
86
|
+
args.push('--enable', rule);
|
|
87
|
+
for (const cat of input.disableCategory ?? [])
|
|
88
|
+
args.push('--disable-category', cat);
|
|
89
|
+
for (const cat of input.enableCategory ?? [])
|
|
90
|
+
args.push('--enable-category', cat);
|
|
91
|
+
for (const pattern of input.ignoreFiles ?? [])
|
|
92
|
+
args.push('--ignore-files', pattern);
|
|
93
|
+
if (input.source !== undefined) {
|
|
94
|
+
return this.withTempSource(input.source, (path) => this.run([...args, path]));
|
|
95
|
+
}
|
|
96
|
+
args.push(...(input.paths ?? []));
|
|
97
|
+
return this.run(args);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Run `regal` with the given argv. Tools should prefer the typed
|
|
101
|
+
* methods above; this is the escape hatch.
|
|
102
|
+
*/
|
|
103
|
+
async run(args) {
|
|
104
|
+
const opts = {
|
|
105
|
+
args,
|
|
106
|
+
timeoutMs: this.config.subprocessTimeoutMs,
|
|
107
|
+
};
|
|
108
|
+
return runBinary(this.config.regalBinary, opts);
|
|
109
|
+
}
|
|
110
|
+
// ─── Internal: temp file management ──────────────────────────────────
|
|
111
|
+
async withTempSource(source, fn) {
|
|
112
|
+
const path = join(tmpdir(), `orygn-opa-mcp-${randomUUID()}.rego`);
|
|
113
|
+
await writeFile(path, source, 'utf8');
|
|
114
|
+
try {
|
|
115
|
+
return await fn(path);
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
await rm(path, { force: true });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=regal-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regal-cli.js","sourceRoot":"","sources":["../../src/lib/regal-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ToolEnvelope } from '../types.js';
|
|
2
|
+
export interface PathValidationResult {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
resolved?: string;
|
|
5
|
+
error?: ToolEnvelope<never>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Resolve `inputPath` and confirm it is contained within at least one
|
|
9
|
+
* `allowedRoots` entry. Returns the resolved absolute path on success.
|
|
10
|
+
*/
|
|
11
|
+
export declare function validatePath(inputPath: string, allowedRoots: string[], options?: {
|
|
12
|
+
mustExist?: boolean;
|
|
13
|
+
}): PathValidationResult;
|
|
14
|
+
/** Convenience: returns true if the path is a directory (after validation). */
|
|
15
|
+
export declare function isDirectory(path: string): boolean;
|
|
16
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/lib/security.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACpC,oBAAoB,CAiDtB;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMjD"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path validation against the configured allow-list.
|
|
3
|
+
*
|
|
4
|
+
* Tools that accept filesystem paths must validate inputs through
|
|
5
|
+
* `validatePath` to prevent reading or writing outside the
|
|
6
|
+
* agreed-upon roots.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, statSync } from 'node:fs';
|
|
9
|
+
import { isAbsolute, resolve, sep } from 'node:path';
|
|
10
|
+
import { err } from './errors.js';
|
|
11
|
+
/**
|
|
12
|
+
* Resolve `inputPath` and confirm it is contained within at least one
|
|
13
|
+
* `allowedRoots` entry. Returns the resolved absolute path on success.
|
|
14
|
+
*/
|
|
15
|
+
export function validatePath(inputPath, allowedRoots, options = {}) {
|
|
16
|
+
if (typeof inputPath !== 'string' || inputPath.length === 0) {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
error: err('INVALID_INPUT', 'Path must be a non-empty string'),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (allowedRoots.length === 0) {
|
|
23
|
+
return {
|
|
24
|
+
ok: false,
|
|
25
|
+
error: err('PATH_NOT_ALLOWED', 'File-based tools are disabled because OPA_MCP_ALLOWED_PATHS is empty.', {
|
|
26
|
+
hint: 'Set OPA_MCP_ALLOWED_PATHS to a comma-separated list of directories the server may read or write.',
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const resolved = isAbsolute(inputPath) ? resolve(inputPath) : resolve(process.cwd(), inputPath);
|
|
31
|
+
const isInsideRoot = allowedRoots.some((root) => {
|
|
32
|
+
const resolvedRoot = resolve(root);
|
|
33
|
+
const rootWithSep = resolvedRoot.endsWith(sep) ? resolvedRoot : resolvedRoot + sep;
|
|
34
|
+
return resolved === resolvedRoot || resolved.startsWith(rootWithSep);
|
|
35
|
+
});
|
|
36
|
+
if (!isInsideRoot) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
error: err('PATH_NOT_ALLOWED', `Path is outside allowed roots: ${inputPath}`, {
|
|
40
|
+
hint: 'Set OPA_MCP_ALLOWED_PATHS to a comma-separated list of directories, or use a path under the current allowed roots.',
|
|
41
|
+
details: { resolved, allowedRoots },
|
|
42
|
+
}),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (options.mustExist && !existsSync(resolved)) {
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
error: err('PATH_NOT_FOUND', `Path does not exist: ${inputPath}`, {
|
|
49
|
+
details: { resolved },
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return { ok: true, resolved };
|
|
54
|
+
}
|
|
55
|
+
/** Convenience: returns true if the path is a directory (after validation). */
|
|
56
|
+
export function isDirectory(path) {
|
|
57
|
+
try {
|
|
58
|
+
return statSync(path).isDirectory();
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/lib/security.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AASlC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,SAAiB,EACjB,YAAsB,EACtB,UAAmC,EAAE;IAErC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,CAAC,eAAe,EAAE,iCAAiC,CAAC;SAC/D,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,CACR,kBAAkB,EAClB,uEAAuE,EACvE;gBACE,IAAI,EAAE,kGAAkG;aACzG,CACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IAEhG,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,GAAG,GAAG,CAAC;QACnF,OAAO,QAAQ,KAAK,YAAY,IAAI,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,CAAC,kBAAkB,EAAE,kCAAkC,SAAS,EAAE,EAAE;gBAC5E,IAAI,EAAE,oHAAoH;gBAC1H,OAAO,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE;aACpC,CAAC;SACH,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,CAAC,gBAAgB,EAAE,wBAAwB,SAAS,EAAE,EAAE;gBAChE,OAAO,EAAE,EAAE,QAAQ,EAAE;aACtB,CAAC;SACH,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface SpawnOptions {
|
|
2
|
+
/** Argument vector passed directly to the binary. */
|
|
3
|
+
args: string[];
|
|
4
|
+
/** Optional stdin payload (e.g., Rego source). */
|
|
5
|
+
stdin?: string;
|
|
6
|
+
/** Working directory for the child process. */
|
|
7
|
+
cwd?: string;
|
|
8
|
+
/** Hard timeout in milliseconds. */
|
|
9
|
+
timeoutMs: number;
|
|
10
|
+
/** Extra environment variables to merge into process.env. */
|
|
11
|
+
env?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export interface SpawnResult {
|
|
14
|
+
exitCode: number | null;
|
|
15
|
+
stdout: string;
|
|
16
|
+
stderr: string;
|
|
17
|
+
timedOut: boolean;
|
|
18
|
+
/** Time spent in milliseconds. */
|
|
19
|
+
durationMs: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Run a binary and return its captured output. Never throws — failures
|
|
23
|
+
* are reflected in `exitCode` / `timedOut`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runBinary(binary: string, opts: SpawnOptions): Promise<SpawnResult>;
|
|
26
|
+
//# sourceMappingURL=subprocess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subprocess.d.ts","sourceRoot":"","sources":["../../src/lib/subprocess.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA8DxF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subprocess wrapper used by `opa-cli.ts` and `regal-cli.ts`.
|
|
3
|
+
*
|
|
4
|
+
* - Uses argv arrays only (never shell strings) — prevents injection.
|
|
5
|
+
* - Hard timeout per invocation, defaulting to config.subprocessTimeoutMs.
|
|
6
|
+
* - Captures stdout / stderr / exit code separately.
|
|
7
|
+
* - Optional stdin payload for piping source code.
|
|
8
|
+
*/
|
|
9
|
+
import { spawn } from 'node:child_process';
|
|
10
|
+
/**
|
|
11
|
+
* Run a binary and return its captured output. Never throws — failures
|
|
12
|
+
* are reflected in `exitCode` / `timedOut`.
|
|
13
|
+
*/
|
|
14
|
+
export async function runBinary(binary, opts) {
|
|
15
|
+
const start = Date.now();
|
|
16
|
+
return await new Promise((resolvePromise) => {
|
|
17
|
+
const child = spawn(binary, opts.args, {
|
|
18
|
+
cwd: opts.cwd,
|
|
19
|
+
env: opts.env ? { ...process.env, ...opts.env } : process.env,
|
|
20
|
+
shell: false,
|
|
21
|
+
windowsHide: true,
|
|
22
|
+
});
|
|
23
|
+
const stdoutChunks = [];
|
|
24
|
+
const stderrChunks = [];
|
|
25
|
+
let timedOut = false;
|
|
26
|
+
let killTimer;
|
|
27
|
+
const timer = setTimeout(() => {
|
|
28
|
+
timedOut = true;
|
|
29
|
+
child.kill('SIGTERM');
|
|
30
|
+
// SIGKILL escalation if SIGTERM is ignored.
|
|
31
|
+
killTimer = setTimeout(() => {
|
|
32
|
+
if (!child.killed)
|
|
33
|
+
child.kill('SIGKILL');
|
|
34
|
+
}, 2_000);
|
|
35
|
+
}, opts.timeoutMs);
|
|
36
|
+
const clearTimers = () => {
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
if (killTimer)
|
|
39
|
+
clearTimeout(killTimer);
|
|
40
|
+
};
|
|
41
|
+
child.stdout?.on('data', (chunk) => stdoutChunks.push(chunk));
|
|
42
|
+
child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
|
|
43
|
+
child.on('error', (e) => {
|
|
44
|
+
clearTimers();
|
|
45
|
+
resolvePromise({
|
|
46
|
+
exitCode: null,
|
|
47
|
+
stdout: '',
|
|
48
|
+
stderr: e.message,
|
|
49
|
+
timedOut: false,
|
|
50
|
+
durationMs: Date.now() - start,
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
child.on('close', (code) => {
|
|
54
|
+
clearTimers();
|
|
55
|
+
resolvePromise({
|
|
56
|
+
exitCode: code,
|
|
57
|
+
stdout: Buffer.concat(stdoutChunks).toString('utf8'),
|
|
58
|
+
stderr: Buffer.concat(stderrChunks).toString('utf8'),
|
|
59
|
+
timedOut,
|
|
60
|
+
durationMs: Date.now() - start,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
if (opts.stdin !== undefined) {
|
|
64
|
+
child.stdin?.write(opts.stdin);
|
|
65
|
+
child.stdin?.end();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
child.stdin?.end();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=subprocess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subprocess.js","sourceRoot":"","sources":["../../src/lib/subprocess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers shared across tool implementations.
|
|
3
|
+
*
|
|
4
|
+
* Each tool follows the same shape — validate input, call into a CLI
|
|
5
|
+
* wrapper or HTTP client, map errors to a structured envelope, return
|
|
6
|
+
* the formatted MCP result. The pieces here factor out the parts every
|
|
7
|
+
* tool repeats so each tool file can stay focused on its own logic.
|
|
8
|
+
*/
|
|
9
|
+
import type { Config } from '../config.js';
|
|
10
|
+
import { type McpToolResult } from './output.js';
|
|
11
|
+
import type { SpawnResult } from './subprocess.js';
|
|
12
|
+
import type { ToolEnvelope } from '../types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Convert a subprocess outcome into a structured tool error envelope
|
|
15
|
+
* for the cases that are universal across all CLI-backed tools:
|
|
16
|
+
* binary missing, subprocess timed out. Returns `undefined` when the
|
|
17
|
+
* subprocess exited normally (exitCode is a number) so the caller can
|
|
18
|
+
* inspect the result.
|
|
19
|
+
*/
|
|
20
|
+
export declare function mapSubprocessFailure(result: SpawnResult, binary: 'opa' | 'regal'): ToolEnvelope<never> | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Try to parse `text` as JSON. Returns `undefined` on failure so the
|
|
23
|
+
* caller can fall back to a textual error envelope rather than throwing.
|
|
24
|
+
*/
|
|
25
|
+
export declare function tryParseJson<T = unknown>(text: string): T | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Validate a list of input paths against the configured allow-list.
|
|
28
|
+
* Returns either an array of resolved absolute paths or a structured
|
|
29
|
+
* error envelope on the first violation.
|
|
30
|
+
*/
|
|
31
|
+
export declare function validatePaths(paths: string[], config: Config, options?: {
|
|
32
|
+
mustExist?: boolean;
|
|
33
|
+
}): {
|
|
34
|
+
ok: true;
|
|
35
|
+
resolved: string[];
|
|
36
|
+
} | {
|
|
37
|
+
ok: false;
|
|
38
|
+
error: ToolEnvelope<never>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Run a tool body, automatically wrapping any thrown exception in a
|
|
42
|
+
* `UNKNOWN_ERROR` envelope and serializing the result. Use this in
|
|
43
|
+
* place of try/catch around every tool handler.
|
|
44
|
+
*/
|
|
45
|
+
export declare function withToolEnvelope<T>(config: Config, body: () => Promise<ToolEnvelope<T>>): Promise<McpToolResult>;
|
|
46
|
+
//# sourceMappingURL=tool-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/tool-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,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,CAmBjC;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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { err } from './errors.js';
|
|
2
|
+
import { formatEnvelope } from './output.js';
|
|
3
|
+
import { validatePath } from './security.js';
|
|
4
|
+
/**
|
|
5
|
+
* Convert a subprocess outcome into a structured tool error envelope
|
|
6
|
+
* for the cases that are universal across all CLI-backed tools:
|
|
7
|
+
* binary missing, subprocess timed out. Returns `undefined` when the
|
|
8
|
+
* subprocess exited normally (exitCode is a number) so the caller can
|
|
9
|
+
* inspect the result.
|
|
10
|
+
*/
|
|
11
|
+
export function mapSubprocessFailure(result, binary) {
|
|
12
|
+
if (result.exitCode === null) {
|
|
13
|
+
const code = binary === 'opa' ? 'OPA_BINARY_NOT_FOUND' : 'REGAL_NOT_FOUND';
|
|
14
|
+
const hint = binary === 'opa'
|
|
15
|
+
? 'Install OPA (https://www.openpolicyagent.org/docs/latest/) or set OPA_BINARY to the absolute path of the binary.'
|
|
16
|
+
: 'Install Regal (https://docs.styra.com/regal) or set REGAL_BINARY to the absolute path of the binary.';
|
|
17
|
+
return err(code, `${binary} binary unreachable: ${result.stderr || 'spawn failed'}`, { hint });
|
|
18
|
+
}
|
|
19
|
+
if (result.timedOut) {
|
|
20
|
+
return err('TIMEOUT', `${binary} subprocess exceeded the configured timeout (OPA_MCP_TIMEOUT_MS).`, {
|
|
21
|
+
details: { durationMs: result.durationMs },
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Try to parse `text` as JSON. Returns `undefined` on failure so the
|
|
28
|
+
* caller can fall back to a textual error envelope rather than throwing.
|
|
29
|
+
*/
|
|
30
|
+
export function tryParseJson(text) {
|
|
31
|
+
if (text.trim().length === 0)
|
|
32
|
+
return undefined;
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(text);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Validate a list of input paths against the configured allow-list.
|
|
42
|
+
* Returns either an array of resolved absolute paths or a structured
|
|
43
|
+
* error envelope on the first violation.
|
|
44
|
+
*/
|
|
45
|
+
export function validatePaths(paths, config, options = {}) {
|
|
46
|
+
const resolved = [];
|
|
47
|
+
for (const path of paths) {
|
|
48
|
+
const result = validatePath(path, config.allowedPaths, options);
|
|
49
|
+
if (!result.ok) {
|
|
50
|
+
return { ok: false, error: result.error };
|
|
51
|
+
}
|
|
52
|
+
if (result.resolved !== undefined)
|
|
53
|
+
resolved.push(result.resolved);
|
|
54
|
+
}
|
|
55
|
+
return { ok: true, resolved };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Run a tool body, automatically wrapping any thrown exception in a
|
|
59
|
+
* `UNKNOWN_ERROR` envelope and serializing the result. Use this in
|
|
60
|
+
* place of try/catch around every tool handler.
|
|
61
|
+
*/
|
|
62
|
+
export async function withToolEnvelope(config, body) {
|
|
63
|
+
try {
|
|
64
|
+
const envelope = await body();
|
|
65
|
+
return formatEnvelope(envelope, config.maxResponseBytes);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
const message = e instanceof Error ? e.message : 'An unknown error occurred';
|
|
69
|
+
const details = e instanceof Error ? { stack: e.stack } : { value: e };
|
|
70
|
+
return formatEnvelope(err('UNKNOWN_ERROR', message, { details }), config.maxResponseBytes);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=tool-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-helpers.js","sourceRoot":"","sources":["../../src/lib/tool-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAgG3C,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAoExE"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Prompts — slash-command-like workflow templates.
|
|
3
|
+
*
|
|
4
|
+
* Each prompt is a stateless instruction set the agent receives when
|
|
5
|
+
* the user invokes it. They orient the agent toward a specific
|
|
6
|
+
* workflow (write a policy, review one, debug a decision) and tell it
|
|
7
|
+
* which of our tools to call in what order.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
const policyAuthoringAssistantPrompt = (args) => {
|
|
11
|
+
const description = args.description ?? '<not provided>';
|
|
12
|
+
const packageName = args.package_name ?? '<choose a package, e.g. authz>';
|
|
13
|
+
return `You are a Rego policy authoring assistant.
|
|
14
|
+
|
|
15
|
+
Goal: produce a working policy for the user's described scenario.
|
|
16
|
+
|
|
17
|
+
User's description:
|
|
18
|
+
${description}
|
|
19
|
+
|
|
20
|
+
Suggested package: ${packageName}
|
|
21
|
+
|
|
22
|
+
Workflow:
|
|
23
|
+
1. Clarify the inputs and decision the policy needs to produce.
|
|
24
|
+
- What does \`input\` look like? (Ask the user if unclear.)
|
|
25
|
+
- What is the boolean or set-valued decision? (allow / deny / reasons)
|
|
26
|
+
2. Draft the policy using \`rego.v1\` syntax. Keep it minimal.
|
|
27
|
+
3. Call \`rego_format\` to canonicalise it.
|
|
28
|
+
4. Call \`rego_check\` on the formatted source. If it returns errors,
|
|
29
|
+
call \`rego_suggest_fix\` with the diagnostics and incorporate the
|
|
30
|
+
suggestions.
|
|
31
|
+
5. Call \`rego_lint\` and address \`error\` and \`warning\` level findings.
|
|
32
|
+
6. Call \`rego_generate_test_skeleton\` and turn the stubs into real
|
|
33
|
+
tests with realistic inputs.
|
|
34
|
+
7. Run \`rego_test\` and iterate until tests pass.
|
|
35
|
+
8. Return the final policy + tests to the user.`;
|
|
36
|
+
};
|
|
37
|
+
const policyReviewChecklistPrompt = (args) => {
|
|
38
|
+
return `You are reviewing the following Rego policy:
|
|
39
|
+
|
|
40
|
+
\`\`\`rego
|
|
41
|
+
${args.source ?? '<paste the policy via the next user message>'}
|
|
42
|
+
\`\`\`
|
|
43
|
+
|
|
44
|
+
Apply this checklist, calling tools as needed:
|
|
45
|
+
|
|
46
|
+
1. **Compiles cleanly.** Run \`rego_check\` with \`strict: true\`.
|
|
47
|
+
2. **Lints cleanly.** Run \`rego_lint\`. Address every \`error\` and
|
|
48
|
+
\`warning\` finding. Note \`notice\` items but don't insist.
|
|
49
|
+
3. **Has tests.** If no \`*_test.rego\` was provided, call
|
|
50
|
+
\`rego_generate_test_skeleton\` and propose tests.
|
|
51
|
+
4. **Default-deny.** Confirm the principal decision (e.g. \`allow\`) has
|
|
52
|
+
a \`default := false\` (or equivalent). If not, flag it.
|
|
53
|
+
5. **No HTTP_SEND.** Search the source for \`http.send\`. If present,
|
|
54
|
+
confirm it's truly necessary; it's a major performance and security
|
|
55
|
+
concern in a policy hot path.
|
|
56
|
+
6. **Annotations.** Check that exported rules have docstrings. If
|
|
57
|
+
missing, suggest minimal \`# METADATA\` annotations.
|
|
58
|
+
7. **Shape of input.** Use \`rego_describe_policy\` to enumerate input
|
|
59
|
+
refs the policy reads; confirm the documented input contract
|
|
60
|
+
matches.
|
|
61
|
+
|
|
62
|
+
Return a concise review with: pass/fail per item, recommended diffs.`;
|
|
63
|
+
};
|
|
64
|
+
const decisionDebuggingWorkflowPrompt = (args) => {
|
|
65
|
+
return `You are debugging an unexpected Rego decision.
|
|
66
|
+
|
|
67
|
+
Query: ${args.query ?? '<not provided — ask the user>'}
|
|
68
|
+
User's expectation: ${args.expectation ?? '<ask the user what they expected>'}
|
|
69
|
+
|
|
70
|
+
Workflow:
|
|
71
|
+
1. Gather inputs.
|
|
72
|
+
- The exact input document the agent saw at decision time.
|
|
73
|
+
- The policy and any data files involved.
|
|
74
|
+
- The actual returned decision (vs. the expected one).
|
|
75
|
+
2. Reproduce the decision with \`rego_eval\` (no flags). Confirm it
|
|
76
|
+
matches the reported outcome.
|
|
77
|
+
3. Re-run with \`rego_explain_decision\` to get a structured trace.
|
|
78
|
+
Identify which rules were evaluated and which fired.
|
|
79
|
+
4. The cause is one of:
|
|
80
|
+
a. **Input mismatch** — the policy expected a different input shape.
|
|
81
|
+
Use \`rego_describe_policy\` to list the refs the policy reads
|
|
82
|
+
and confirm each is present in the input.
|
|
83
|
+
b. **Rule logic** — a guard fired or didn't fire when it should
|
|
84
|
+
have. Read the trace and explain which rule's body evaluated to
|
|
85
|
+
true/false and why.
|
|
86
|
+
c. **Default decision** — no rule produced a value, so the default
|
|
87
|
+
kicked in.
|
|
88
|
+
5. Propose the smallest fix: either an input correction or a policy
|
|
89
|
+
change. If a policy change, run \`rego_check\` and \`rego_test\` on the
|
|
90
|
+
patched policy before declaring it fixed.
|
|
91
|
+
|
|
92
|
+
Be specific in the explanation: cite rule names, line numbers, and the
|
|
93
|
+
exact input value that flipped each guard.`;
|
|
94
|
+
};
|
|
95
|
+
export function registerPrompts(server, _config) {
|
|
96
|
+
server.registerPrompt('policy_authoring_assistant', {
|
|
97
|
+
title: 'Policy authoring assistant',
|
|
98
|
+
description: 'Guides an agent through writing a new Rego policy: clarify decision shape, draft, format, check, lint, test, iterate.',
|
|
99
|
+
argsSchema: {
|
|
100
|
+
description: z.string().optional().describe('What the policy needs to enforce.'),
|
|
101
|
+
package_name: z.string().optional().describe('Suggested package path (e.g. "authz").'),
|
|
102
|
+
},
|
|
103
|
+
}, (args) => ({
|
|
104
|
+
messages: [
|
|
105
|
+
{
|
|
106
|
+
role: 'user',
|
|
107
|
+
content: { type: 'text', text: policyAuthoringAssistantPrompt(args) },
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
}));
|
|
111
|
+
server.registerPrompt('policy_review_checklist', {
|
|
112
|
+
title: 'Policy review checklist',
|
|
113
|
+
description: 'Review checklist for an existing Rego policy: compile, lint, tests, default-deny, http.send, annotations, input shape.',
|
|
114
|
+
argsSchema: {
|
|
115
|
+
source: z
|
|
116
|
+
.string()
|
|
117
|
+
.optional()
|
|
118
|
+
.describe('Rego source to review. Optional — agent can ask for it.'),
|
|
119
|
+
},
|
|
120
|
+
}, (args) => ({
|
|
121
|
+
messages: [
|
|
122
|
+
{
|
|
123
|
+
role: 'user',
|
|
124
|
+
content: { type: 'text', text: policyReviewChecklistPrompt(args) },
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
}));
|
|
128
|
+
server.registerPrompt('decision_debugging_workflow', {
|
|
129
|
+
title: 'Decision debugging workflow',
|
|
130
|
+
description: 'Diagnostic flow for an unexpected Rego decision: reproduce, explain trace, identify input vs logic vs default cause, propose minimal fix.',
|
|
131
|
+
argsSchema: {
|
|
132
|
+
query: z
|
|
133
|
+
.string()
|
|
134
|
+
.optional()
|
|
135
|
+
.describe('The Rego query that produced the unexpected result.'),
|
|
136
|
+
expectation: z.string().optional().describe('What the user expected to happen.'),
|
|
137
|
+
},
|
|
138
|
+
}, (args) => ({
|
|
139
|
+
messages: [
|
|
140
|
+
{
|
|
141
|
+
role: 'user',
|
|
142
|
+
content: { type: 'text', text: decisionDebuggingWorkflowPrompt(args) },
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,MAAM,8BAA8B,GAAG,CAAC,IAGvC,EAAU,EAAE;IACX,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,gBAAgB,CAAC;IACzD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,gCAAgC,CAAC;IAC1E,OAAO;;;;;EAKP,WAAW;;qBAEQ,WAAW;;;;;;;;;;;;;;;gDAegB,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,CAAC,IAAyB,EAAU,EAAE;IACxE,OAAO;;;EAGP,IAAI,CAAC,MAAM,IAAI,8CAA8C;;;;;;;;;;;;;;;;;;;;;qEAqBM,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,+BAA+B,GAAG,CAAC,IAGxC,EAAU,EAAE;IACX,OAAO;;SAEA,IAAI,CAAC,KAAK,IAAI,+BAA+B;sBAChC,IAAI,CAAC,WAAW,IAAI,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;2CAyBlC,CAAC;AAC5C,CAAC,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,OAAe;IAChE,MAAM,CAAC,cAAc,CACnB,4BAA4B,EAC5B;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EACT,uHAAuH;QACzH,UAAU,EAAE;YACV,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YAChF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;SACvF;KACF,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACT,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B,CAAC,IAAI,CAAC,EAAE;aACtE;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,yBAAyB,EACzB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,wHAAwH;QAC1H,UAAU,EAAE;YACV,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yDAAyD,CAAC;SACvE;KACF,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACT,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,2BAA2B,CAAC,IAAI,CAAC,EAAE;aACnE;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,6BAA6B,EAC7B;QACE,KAAK,EAAE,6BAA6B;QACpC,WAAW,EACT,2IAA2I;QAC7I,UAAU,EAAE;YACV,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,qDAAqD,CAAC;YAClE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;SACjF;KACF,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACT,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,CAAC,IAAI,CAAC,EAAE;aACvE;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resources — read-only references the agent can fetch by URI.
|
|
3
|
+
*
|
|
4
|
+
* - opa://builtins — derived at read-time from `opa capabilities`.
|
|
5
|
+
* - opa://style-guide — curated Rego style guide content.
|
|
6
|
+
* - opa://patterns — pattern library: RBAC, ABAC, K8s admission,
|
|
7
|
+
* IaC gates, API authz, rate limiting.
|
|
8
|
+
*/
|
|
9
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
10
|
+
import type { Config } from '../config.js';
|
|
11
|
+
export declare function registerResources(server: McpServer, config: Config): void;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAuF3C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAmEzE"}
|