Generate Rego test skeleton
rego_generate_test_skeletonGenerates a *_test.rego skeleton from a Rego policy, creating one stub test per rule for easier unit test writing.
Instructions
Generate a *_test.rego skeleton from a policy. Parses the AST, finds each rule, and emits one stub test per rule. The agent fills in realistic inputs and assertions.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Rego source to generate tests for. |
Implementation Reference
- Handler function: registers the tool with MCP server; parses Rego source via 'opa parse', extracts package name and rule names from AST, generates a test skeleton file with one stub test per rule.
export function registerRegoGenerateTestSkeleton(server: McpServer, config: Config): void { const opa = new OpaCli(config); server.registerTool( 'rego_generate_test_skeleton', { title: 'Generate Rego test skeleton', description: 'Generate a `*_test.rego` skeleton from a policy. Parses the AST, finds each rule, and emits one stub test per rule. The agent fills in realistic inputs and assertions.', inputSchema: RegoGenerateTestSkeletonInput, }, async ({ source }) => { return withToolEnvelope<RegoGenerateTestSkeletonOutput>(config, async () => { const result = await opa.parse({ source }); const subprocessFailure = mapSubprocessFailure(result, 'opa'); if (subprocessFailure) return subprocessFailure; if (result.exitCode !== 0) { return err('INVALID_REGO', 'opa parse rejected the source.', { details: { stderr: result.stderr.trim() }, }); } const ast = tryParseJson<ParsedAst>(result.stdout); if (ast === undefined) { return err('UNKNOWN_ERROR', 'opa parse produced no parseable JSON.'); } const packageName = packageNameFromAst(ast); const ruleNames = Array.from( new Set( (ast.rules ?? []) .map(ruleNameFromAst) .filter((n): n is string => typeof n === 'string' && n.length > 0), ), ); if (ruleNames.length === 0) { return err('INVALID_INPUT', 'No rules found in the source — nothing to test.'); } const testFile = makeSkeleton(packageName, ruleNames); return ok<RegoGenerateTestSkeletonOutput>({ testFile, ruleNames }); }); }, ); } - Input schema: single 'source' string parameter (Zod schema) validated as non-empty string.
const RegoGenerateTestSkeletonInput = { source: z.string().min(1).describe('Rego source to generate tests for.'), }; - Output type: contains 'testFile' (the generated test Rego code) and 'ruleNames' (list of extracted rule names).
export interface RegoGenerateTestSkeletonOutput { testFile: string; ruleNames: string[]; } - src/tools/helpers/index.ts:17-22 (registration)Registration in helper tools category: calls registerRegoGenerateTestSkeleton as part of registerHelperTools.
export function registerHelperTools(server: McpServer, config: Config): void { registerRegoExplainDecision(server, config); registerRegoGenerateTestSkeleton(server, config); registerRegoDescribePolicy(server, config); registerRegoSuggestFix(server, config); } - src/tools/index.ts:37-43 (registration)Top-level registration: registerHelperTools is called from the main registerTools entry point.
export function registerTools(server: McpServer, config: Config): void { registerAuthoringTools(server, config); registerEvaluationTools(server, config); registerBundleTools(server, config); registerServerManagementTools(server, config); registerHelperTools(server, config); }