opa-mcp-server
Turn any MCP-compatible client into a full OPA/Rego authoring, evaluation, testing, and OPA-server management environment via 52 tools, 3 prompts, and 3 curated resources.
Author & analyze Rego — format (
rego_format,rego_format_write), check (rego_check,rego_check_schema), lint with Regal (rego_lint), parse to AST (rego_parse_ast), inspect bundles (rego_inspect), list capabilities (rego_capabilities), dependency analysis (rego_deps), and migrate v0→v1 (rego_migrate_v1).Evaluate & debug decisions — run queries (
rego_eval,rego_eval_with_explain,rego_eval_with_profile,rego_eval_with_coverage,rego_compile_query), batch over many inputs (opa_exec), and explain why a rule fired or is undefined (rego_explain_decision,rego_explain_undefined).Test & benchmark — run unit tests (
rego_test,rego_test_multiroot), find coverage gaps (rego_coverage_gaps), and benchmark hot rules (rego_bench).Build, sign & verify bundles — package deployable
.tar.gzbundles (opa_bundle_build), sign directories (opa_bundle_sign), and verify signatures (opa_bundle_verify).Manage a running OPA server — list/get/put/delete policies, read/write/patch/delete data, query decisions, compile queries, and check health/status/config over the REST API (
opa_*tools).Higher-level agent helpers — generate test skeletons (
rego_generate_test_skeleton), describe policies (rego_describe_policy), suggest fixes (rego_suggest_fix), auto-fix with Regal (rego_fix), security-audit (rego_security_audit), infer input schemas (rego_infer_input_schema), diff two policies (rego_policy_diff), formally verify rules with Z3 (rego_verify), and share policies as GitHub Gists (rego_playground_share).Test config files with conftest — evaluate Kubernetes/Terraform/Dockerfile/Helm configs (
conftest_test), verify conftest policies (conftest_verify), and pull/push policy bundles from OCI or Git (conftest_pull,conftest_push).Meta & curated context — report server/binary versions (
mcp_server_info), plus bundled prompts for policy authoring, review, and decision debugging, and resources for OPA builtins, the Rego style guide, and a common-pattern library (RBAC, ABAC, K8s admission, IaC gates, API authz, rate limiting).
OPA MCP Server
A Model Context Protocol (MCP) server that turns any MCP-compatible client (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed, and others) into a first-class Open Policy Agent and Rego authoring environment.
+--------------------+ MCP/stdio +-----------------+ spawn/HTTP +---------------------+
| Claude · Cursor · |----------> | @orygn/opa-mcp |----------> | opa · regal |
| VS Code · ... |<---------- | |<---------- | conftest · REST API |
+--------------------+ 52 tools +-----------------+ +---------------------+Status: v0.8.0. Tool surface, error codes, and environment variables follow SemVer from v0.1.0 forward.
Upgrading to 0.8.0:
opa_execloadsdataPathsasopa eval --datadoes, so a directory that also holds test fixtures, or JSON and YAML that is not data, can now fail to load; pass it asbundleto load it as before. A policy that does not load isINVALID_REGOinopa_execand the conftest tools, where it wasEVAL_ERRORandUNKNOWN_ERROR.
Upgrading to 0.7.0: Node.js 22 or later is required. The bundled OPA is 1.21, which reads YAML against the 1.2 schema: bare
yes,no,onandoffin data files are strings now, not booleans. If you supply your own binary viaOPA_BINARYorPATH, only the Node requirement applies.
Upgrading to 0.6.0:
rego_benchreportsiterations,nsPerOp,allocsPerOpandbytesPerOp. The fields opa prints (N,T,Bytes,MemAllocs,MemBytes,Extra) were top-level and now sit underrawfor a single run, so anything that read them from the top level has to look there. Withcountabove one,rawis omitted: every document is inruns, andfastestindexes the one the top-level figures come from.
Upgrading to 0.4.0: subprocesses no longer inherit the server's environment. A policy that read a variable through
opa.runtime().envwill no longer see it; name the variable inOPA_MCP_PASSTHROUGH_ENVif it is genuinely needed. See the security section for why.
Upgrading to 0.3.0: the bundled OPA is now 1.19, so Rego v0 policies no longer parse (
ifis required before a rule body,containsbefore a partial set). Runrego_migrate_v1to convert them, or passv0Compatible: trueto load one as it is. If you supply your own binary viaOPA_BINARYorPATH, nothing changes.
Table of contents
Related MCP server: kubernetes-mcp
What you can do with it
Once an MCP client is connected, an agent can:
Author Rego. Generate, format, and refactor policies. The server runs the real
opa fmtandopa parseso output is byte-identical to what you'd get on the command line, andregal(optional) surfaces idiomatic suggestions.Evaluate against data. Run a query against a policy and an input document. Optional
--explain,--profile, and--coverageflags surface execution traces, hot rules, and per-line coverage.Debug a deny.
rego_explain_decisionwalks the agent through every rule that fired (and every one that didn't), so it can answer "why was this rejected" without you reading the trace by hand.Manage policies on a running OPA. List, get, put, delete policies on an OPA server through its REST API. Works against a local
opa run --serveror a production deployment with bearer-token auth.Build & sign bundles. Package a directory of policies into a deployable bundle, optionally signing it. Output is a regular
.tar.gzthe agent can hand to your delivery system.Lint.
rego_lintruns Regal across a directory or a single file and returns each finding with its category, level and location.
A walk-through of a typical session lives in Cookbook.
Why this MCP
OPA already has a perfectly good CLI and REST API. So why an MCP wrapper?
Schema-shaped tool surface. An agent calling
rego_evalgets a validated input schema, a structured output envelope, and stable error codes, instead of parsing free-form CLI text and inventing its own failure taxonomy. That alone makes Rego usable to an agent the way a language server makes a language usable to an IDE.Higher-level helpers.
rego_explain_decision,rego_generate_test_skeleton,rego_describe_policy, andrego_suggest_fixcompose the lower-level primitives into the tasks agents are actually asked to do. They don't exist in the OPA CLI.Curated knowledge. The bundled MCP resources expose the OPA built-in function catalog, the official Rego style guide (formatted for LLMs), and a curated pattern library covering RBAC, ABAC, Kubernetes admission, IaC gates, API authz, and rate limiting, so the agent has authoritative context without needing to scrape it.
Safety boundaries the agent can rely on. Path allow-list, subprocess timeouts, and response-size caps. Defaults are conservative; running the server doesn't quietly grant the agent more reach than the operator intended.
If you've ever watched an agent fight opa eval's argument order, you'll
recognize the gap this fills.
Install
The server runs locally over stdio. Pick the install path that matches your client.
Claude Desktop
Edit claude_desktop_config.json directly (or copy from
examples/claude-desktop.json):
{
"mcpServers": {
"opa": {
"command": "npx",
"args": ["-y", "@orygn/opa-mcp"],
"env": {
"OPA_BINARY": "/usr/local/bin/opa",
"REGAL_BINARY": "/usr/local/bin/regal",
"OPA_URL": "http://localhost:8181",
"OPA_MCP_ALLOWED_PATHS": "/path/to/your/policies"
}
}
}
}Replace the
/usr/local/bin/...paths with your real ones. See the first-time install gotcha below. Windows users substituteC:\\path\\to\\opa.exe.
Or download opa-mcp.mcpb from the
latest release
and double-click it.
Alternatively, use the Smithery one-liner:
npx -y @smithery/cli install @orygn/opa-mcp --client claudeClaude Code (CLI)
Register the server for the current project with claude mcp add:
claude mcp add \
--env OPA_BINARY=/usr/local/bin/opa \
--env REGAL_BINARY=/usr/local/bin/regal \
--env OPA_MCP_ALLOWED_PATHS=/path/to/your/policies \
opa -- npx -y @orygn/opa-mcpThis writes the config into .mcp.json at your project root and is
picked up automatically on every claude session in that directory.
Add --scope user to register it globally instead.
Replace the paths with your real absolute paths (same caveat as Claude Desktop above). On Windows use
C:\path\to\opa.exesyntax.
Persistent context and auto-checks for policy repos. If you work in an OPA policy repo regularly, two extra files remove repetitive setup from every session:
examples/CLAUDE.md-- copy to your repo root or.claude/CLAUDE.md. Claude Code loads it every session, so the agent always knows which tools to use and what conventions apply.examples/claude-code-hook.json-- merge thehooksblock into.claude/settings.json. Runsopa checkautomatically after any.regofile is written, so syntax errors surface immediately without a manual tool call.
Cursor
Drop examples/cursor.json into either
.cursor/mcp.json (project-scoped) or ~/.cursor/mcp.json (user-scoped).
VS Code (GitHub Copilot Chat)
Drop examples/vscode.json into
.vscode/mcp.json, or paste the servers block into your user
settings.json under mcp.servers.
Windsurf, Zed, and others
See examples/ for a full set of drop-in configs.
Manual install (any MCP client)
npm install -g @orygn/opa-mcp
opa-mcp --versionthen point your client at the opa-mcp binary.
Docker
docker pull orygn/opa-mcp:latest
docker run --rm -i \
-v /path/to/your/policies:/policies:ro \
-e OPA_MCP_ALLOWED_PATHS=/policies \
orygn/opa-mcpThe image is multi-arch (linux/amd64, linux/arm64), bundles pinned
versions of opa and regal, and runs as a non-root user. No host
install of OPA or Regal is required.
⚠ If every tool call returns OPA_BINARY_NOT_FOUND
The npm package carries its own opa for the five platforms it is built
for, so a client PATH without opa on it does not matter there. The MCPB
has no bundled copy, and on any other platform neither does npm: then the
server boots but every tool call returns OPA_BINARY_NOT_FOUND. Neither the
npm package nor the MCPB bundles regal or conftest, and the Docker image
ships regal but not conftest, so their tools need a PATH entry or an
explicit path either way.
Fix: add OPA_BINARY and REGAL_BINARY env entries to your client
config with the absolute path to each binary. The example configs under
examples/ ship with placeholder paths you replace.
Find the real paths with:
which opa && which regal # macOS / LinuxGet-Command opa, regal | Select-Object Source # WindowsThis does not affect the Docker install path, which ships opa and
regal in the image and bypasses PATH entirely. The MCPB bundle
carries neither, and unlike the npm install has no bundled fallback: set
OPA_BINARY or put opa on PATH.
See Troubleshooting for full detail.
Configuration
The server reads its configuration from environment variables. Every
variable is optional; defaults are sensible for a local OPA on
http://localhost:8181.
Variable | Default | Purpose |
|
| Base URL of an OPA REST endpoint, used by |
| (unset) | Bearer token for OPA, if your instance requires auth. Treated as a secret. Never echoed in logs or tool responses. |
|
| Path to the |
|
| Path to the |
|
| Path to the |
| (unset) | Comma- or semicolon-separated list of directories the server is allowed to read policies from. When unset, file-based tools refuse to read from disk. |
|
| Path the server appends logs to. The server never writes to stdout; that channel is reserved for the MCP protocol. |
|
| One of |
|
| Hard cap on a single tool response. Larger payloads are truncated with a |
|
| Hard timeout for any spawned subprocess ( |
|
| Timeout for each request to the OPA REST API, from the connection attempt to the last byte of the response; reported as |
| (unset) | Set to |
|
| Maximum bytes captured from a subprocess's stdout and stderr, counted separately. On overflow the stream is clamped, the child is stopped, and the tool returns |
| (unset) | Comma-separated variable names to pass through to |
| (unset) | Comma-separated variable names to withhold from |
Paths in OPA_MCP_ALLOWED_PATHS must be absolute, and a *_BINARY value is
either a bare command name looked up on PATH or an absolute path; anything
else stops the server at startup. A binary that cannot be run is reported by
each tool call with a structured error.
Tool reference
Every tool returns a JSON envelope:
{ "ok": true, "data": { ... }, "warnings": [ ... ] }
{ "ok": false, "error": { "code": "INVALID_REGO", "message": "...", "hint": "...", "details": { ... } } }Stable error codes: INVALID_INPUT, INVALID_REGO, INVALID_BUNDLE,
EVAL_ERROR, OPA_BINARY_NOT_FOUND, REGAL_NOT_FOUND,
CONFTEST_NOT_FOUND, OPA_UNREACHABLE, OPA_AUTH_FAILED,
POLICY_NOT_FOUND, DATA_NOT_FOUND, PATH_NOT_ALLOWED, PATH_NOT_FOUND,
NO_TESTS_FOUND, COVERAGE_BELOW_THRESHOLD, OPA_VERSION_UNSUPPORTED,
GITHUB_TOKEN_MISSING, GIST_CREATE_FAILED, OUTPUT_TOO_LARGE, SUBPROCESS_KILLED, OPA_URL_INVALID, TIMEOUT,
CANCELLED, UNKNOWN_ERROR. A rego_eval batch can also give an entry
NOT_EVALUATED: an input the call stopped before reaching, after another
timed out.
Category A: Authoring & static analysis
Operate on Rego source code without needing a running OPA server. Wrap
opa fmt, opa parse, opa check, opa inspect, opa capabilities,
opa deps, and regal.
Tool | What it does |
| Format Rego source. Wraps |
| Type-check and validate Rego. Wraps |
| Run Regal across a file or directory. Returns each violation with its category, level and location. Requires |
| Parse Rego to AST JSON. Wraps |
| Inspect a bundle or directory: packages, rules, annotations. Wraps |
| List the built-ins and features the resolved |
| Static dependency analysis: rule-level data references and cross-package calls. |
| Migrate Rego v0 source to v1. Renames a rule v1 reserves the name of ( |
| Check Rego against a JSON Schema. Validates that every |
Featured: rego_format
// Input
{
"source": "package x\nallow if input.user==\"admin\""
}
// Output (ok)
{
"ok": true,
"data": {
"formatted": "package x\n\nallow if input.user == \"admin\"\n",
"changed": true
}
}Featured: rego_check
// Input
{
"source": "package x\nallow if y",
"strict": true
}
// Output (error path; the JSON diagnostics arrive on stderr from opa)
{
"ok": true,
"data": {
"valid": false,
"errors": [
{
"code": "rego_unsafe_var_error",
"message": "var y is unsafe",
"location": { "row": 2, "col": 11 }
}
]
}
}Category B: Evaluation & testing
Run a query against a policy and input. Wrap opa eval, opa test, and
opa bench. Each of these tools takes v0Compatible to load a policy
written before OPA 1.0 without migrating it, and so does every other tool
that reads a policy through opa or conftest, from rego_check to
rego_verify and conftest_test. OPA then reads the query as v0 too, so
the future keywords are imported for it and in and every still work
there. rego_policy_diff takes it per side (v0CompatibleA,
v0CompatibleB), to compare a legacy policy with its migrated copy. The
exceptions are rego_deps, since opa deps has no such option, and the
Regal tools, which need none, since Regal reads either version.
Tool | What it does |
| Evaluate a query against a policy and input. The bread-and-butter tool. |
| Evaluate with |
| Evaluate with |
| Evaluate with |
| Run Rego unit tests with |
| Run |
| Partially evaluate a query against a policy. |
| Batch-evaluate a decision against multiple input files. Returns per-file results with |
| Run |
Featured: rego_eval
// Input
{
"query": "data.rbac.allow",
"source": "package rbac\nimport rego.v1\nallow if input.role == \"admin\"",
"input": { "role": "admin" }
}
// Output
{
"ok": true,
"data": {
"result": [{ "expressions": [{ "value": true, "text": "data.rbac.allow", "location": { "row": 1, "col": 1 } }] }]
}
}Category C: Bundle operations
Package, sign, and verify deployable bundles. Wrap opa build, opa sign, and opa build --verification-key.
Tool | What it does |
| Build a |
| Sign a bundle directory in place with a private key; an archive is refused, since OPA reads the signature from inside it, and comes signed from |
| Verify a signed bundle with a public key through |
Category D: OPA server management
Talk to a running OPA server over its REST API. Require OPA_URL to
point at a reachable server.
Tool | What it does |
| List the policy IDs registered on the server, with a count. |
| Get a single policy by ID. Returns the Rego source; |
| Upload or replace a policy. |
| Delete a policy by ID. |
| Read a path from the data hierarchy. |
| Write to a path in the data hierarchy. |
| Apply a JSON Patch to the data hierarchy. |
| Delete a document from the data hierarchy. |
| POST to a |
| Partially evaluate a query against the running server. |
| Liveness / readiness check. A server that answers reports |
| The same |
| Server configuration from |
Category E: Higher-level helpers
The differentiation surface. These compose lower-level primitives into the tasks agents are actually asked to do.
Tool | What it does |
| Turn an evaluation trace into a structured per-rule summary of what fired and what did not |
| Given a policy, generate a |
| Summarize a policy's package, imports and per-rule structure from its AST. For the input references a policy reads, use |
| For a failed |
| Run |
| Run regal lint restricted to its |
| Statically analyse a policy (or directory of policies) with |
| Run |
| Run |
| Evaluate the same query against two policies in parallel and compare the results. Returns |
| Formally verify a property about a Rego rule using SMT solving (Microsoft Z3 via WASM). Unlike testing, this checks ALL possible inputs mathematically and either proves the property holds or returns a concrete counterexample. The |
| Explain why a Rego query is undefined. Combines a plain eval, a full-trace eval, and per-condition AST analysis to identify the exact body expression blocking each rule. Returns a structured breakdown of which conditions blocked each rule plus a human-readable summary. |
| Publish a policy (and optional input) as a secret GitHub Gist (pass |
Category F: Conftest (configuration policy testing)
Test Kubernetes manifests, Terraform plans, Dockerfiles, Helm charts, and any
YAML/JSON/HCL/TOML/INI against Rego policies using
conftest. Requires conftest on PATH or
CONFTEST_BINARY set; all four tools return CONFTEST_NOT_FOUND otherwise.
Tool | What it does |
| Evaluate config files or an inline document against Rego policies with |
| Run the |
| Pull a policy bundle from an OCI registry or Git repo into a local directory with |
| Package a local policy directory as an OCI artifact and push to a registry with |
Featured: conftest_test with inline config
// Input
{
"inlineConfig": "apiVersion: v1\nkind: Pod\nspec:\n containers:\n - name: app\n image: nginx:latest",
"inlinePolicy": "package main\ndeny contains msg if { input.spec.containers[_].image == \"nginx:latest\"; msg := \"pin your image tag\" }"
}
// Output
{
"ok": true,
"data": {
"passed": false,
"results": [
{
"filename": "<inline>",
"namespace": "main",
"successes": 0,
"failures": [{ "msg": "pin your image tag" }],
"warnings": [],
"skipped": [],
"exceptions": []
}
],
"summary": {
"passed": 0,
"failed": 1,
"warnings": 0,
"skipped": 0,
"successes": 0,
"failures": 1
}
}
}Category G: Meta
Tool | What it does |
| Return server name, version, resolved |
Prompts
Three MCP prompts ship with the server. Clients surface them as slash commands or workflow templates.
Prompt | Purpose |
| Walks the agent through writing a new policy: ask about the decision surface, draft, review, format, lint, test. |
| Review checklist for an existing policy: completeness, edge cases, performance, security pitfalls. |
| Diagnostic flow when a decision is unexpected: gather input, run with explain, isolate the rule, propose a fix. |
Resources
Three MCP resources expose curated reference data the agent can read at any time.
Resource URI | What's there |
| Categorized OPA built-in function reference, derived at read time from |
| Condensed Rego style guide, formatted for LLM consumption. |
| Curated common-pattern library: RBAC, ABAC, Kubernetes admission, IaC gates, API authz, rate limiting. Each pattern includes when-to-use, full Rego, a test, and common pitfalls. |
Cookbook
A few session shapes that the tool set was designed for.
"Help me write a policy"
You: I need an authz policy: editors can read/write, viewers can only read,
admins can do anything.
Agent: I'll draft it. (calls rego_format on a draft, then rego_check, then
rego_lint)
Agent: Here's the policy. I've also generated a test file with cases for
each role. (calls rego_generate_test_skeleton, then rego_test)
Agent: All 9 tests pass. Want me to save it to <path>?"Why was this denied?"
You: This API call is being denied and I don't know why.
[pastes input.json]
Agent: (calls rego_explain_decision against your local policy with that input)
Agent: The deny comes from rule `forbid_anonymous_writes` at line 17.
Specifically, `input.user` is null and the request method is "POST".
The rule fires, which causes the default deny. To allow this, you'd
need either an authenticated user or a policy exception for this
endpoint."Push this policy to staging OPA"
You: Push policies/rbac.rego to the staging OPA server, but first lint and
test it.
Agent: (rego_lint → 2 style warnings, no errors)
(rego_test on policies/ → all pass)
(opa_put_policy with id="rbac" against $OPA_URL)
(opa_get_policy to verify)
Agent: Done. Policy `rbac` is live on staging at $OPA_URL.Architecture
┌──────────────────────────────────── @orygn/opa-mcp ───────────────────────────────────┐
│ │
│ src/server.ts ──── McpServer (stdio) ─── tool / prompt / resource registries │
│ │ │
│ ├── tools/authoring/ ─┐ │
│ ├── tools/evaluation/ ─┤ │
│ ├── tools/bundles/ ─┼─── lib/opa-cli.ts ──┐ │
│ ├── tools/server-management/ ─┤ │ │
│ ├── tools/helpers/ ─┤ │ │
│ ├── tools/conftest/ ─┤ │ │
│ ├── tools/meta/ ─┘ │ │
│ │ ▼ │
│ │ lib/subprocess.ts ──┴── opa │
│ │ lib/regal-cli.ts ───── regal│
│ │ lib/conftest-cli.ts ─ conftest│
│ │ lib/opa-client.ts ───── HTTP │
│ │ │
│ └── lib/output.ts (envelope + truncation) │
│ lib/security.ts (path allow-list) │
│ lib/errors.ts (structured failures) │
│ lib/logger.ts (file-only, never stdout) │
└───────────────────────────────────────────────────────────────────────────────────────┘Four things worth knowing if you're going to operate this:
stdout is the protocol channel. The server logs to a file via
lib/logger.tsand never writes to stdout. If you see stray stdout bytes, the client disconnects; the MCP transport layer is strict.No tool handler throws. Every handler catches its own exceptions and returns a structured
{ ok: false, error: ... }envelope, so the agent sees a stable error vocabulary, not a stack trace. An argument that fails the tool's input schema never reaches the handler: the MCP layer rejects it and returns a tool result withisError: truewhose text beginsMCP error -32602: Input validation error:, rather than the envelope. Decoding subprocess output happens inside an async callback, where a throw would bypass those handlers entirely, so that path is bounded by bytes rather than left to atry/catchthat could not see it.Subprocesses are bounded in time, size, and environment.
lib/subprocess.tsruns the binaries withshell: false, a hard timeout withSIGTERM-then-SIGKILLescalation, and a per-stream byte cap. There is no path through the server where an agent can construct a shell command. The timeout alone is not enough:opabuffers a result in memory and writes it in one burst at exit, so a command that finishes well inside the timeout can still deliver hundreds of megabytes.Children do not inherit the server's environment.
lib/child-env.tsbuilds an explicit allow-list instead. Rego can read its interpreter's environment throughopa.runtime().env, so anything passed down is readable by any policy the server evaluates, the proxy variables on the list included.
Security
This server is designed to run locally, started by an MCP client on the user's own machine, communicating over stdio. It is not designed to be exposed on the network.
File-based tools refuse to read anything outside
OPA_MCP_ALLOWED_PATHS. When that variable is unset, file tools returnPATH_NOT_ALLOWED.Subprocesses run with
shell: false, a hard timeout, and a byte cap on captured output.Evaluated policy cannot read the server's environment. Rego exposes the environment of the
opaprocess throughopa.runtime().env, so a child that inheritedprocess.envwould handOPA_TOKEN,GITHUB_TOKEN, and every other variable to any policy it evaluated. Sincerego_evalaccepts inline source, no filesystem access is needed to reach that, which puts it one prompt injection away from any untrusted Rego an agent reads. Children get an explicit allow-list instead (lib/child-env.ts). The list holds no cloud or repository token, but it is not free of credentials:HTTP_PROXYand its siblings are on it, and a proxy URL can embed a username and password. They are there because dropping them breaks everyone behind a corporate proxy. Name them inOPA_MCP_BLOCK_ENVto withhold them anyway.OPA_MCP_PASSTHROUGH_ENVopts individual variables back in.OPA_TOKENis never echoed in tool responses or log entries, and is not passed to any child process.Tools that evaluate Rego are annotated open-world and not read-only.
rego_evaland its variants,rego_test,rego_test_multiroot,rego_bench,rego_compile_query,opa_exec,rego_migrate_v1(when giveninputs), the explain, diff and coverage helpers, the conftest tools, and the Regal tools (rego_lint,rego_security_audit,rego_fix, which run a project's custom rules) all run Rego, and OPA'shttp.sendlets a policy reach, and write to, any network address. A client that gates on the hints will ask before running one.opa_query_decisionandopa_compile_queryare the exception: the remote OPA evaluates a policy it already holds, and their hints describe what the call does to that server. No evaluating tool passes or accepts a capabilities file, sohttp.sendcannot be restricted for evaluation;rego_checkandopa_bundle_buildaccept one, which affects only checking and building.Releases are published with npm provenance; the Docker image is built from the committed
Dockerfile, with pinned versions ofopaandregalchecked against their published digests.
To report a vulnerability, follow SECURITY.md. Please do not open a public issue for security problems.
Troubleshooting
Common issues, fast fixes.
OPA_BINARY_NOT_FOUND (or REGAL_NOT_FOUND / CONFTEST_NOT_FOUND) even
though the binary is installed. (most common first-day issue, read this
first)
MCP clients (notably Claude Desktop on Windows and macOS) launch the
server with a deliberately reduced PATH that omits user-local bin
directories, even ones that work fine in your interactive shell. The
binary is on your machine; the spawned MCP server just can't see it.
Find the absolute path to opa:
# macOS / Linux
which opa
# → /usr/local/bin/opa (or /opt/homebrew/bin/opa, or ~/.local/bin/opa)# Windows
Get-Command opa | Select-Object -ExpandProperty Source
# → C:\Users\you\bin\opa.exe (or wherever)Then set OPA_BINARY to that absolute path in your client's MCP env
block. The same cause and fix apply to the other binaries: if rego_lint
/ rego_security_audit / rego_fix report REGAL_NOT_FOUND, or the
conftest_* tools report CONFTEST_NOT_FOUND, set REGAL_BINARY /
CONFTEST_BINARY to the absolute path the same way (find it with
which regal / which conftest). Having the binary on your shell PATH
is not enough -- the spawned server gets a reduced PATH. The
examples/ configs already include these env vars; just
edit the placeholder paths.
This issue does not affect the Docker install path, which bundles
opa and regal and bypasses PATH entirely. The MCPB bundle resolves
opa from OPA_BINARY or PATH, so it can hit this.
The server starts, then the client says "disconnected."
The most likely cause is something in the process writing to stdout
besides MCP frames. If you've added a custom tool, check that no library
it calls prints to stdout. The fixed-position safety net is
lib/logger.ts. Use it, not console.log.
PATH_NOT_ALLOWED on a file under my project.
OPA_MCP_ALLOWED_PATHS is empty by default. Set it to the absolute
path(s) you want the server to read from, comma-separated.
OPA_UNREACHABLE when calling opa_* tools.
OPA_URL (default http://localhost:8181) must point at a running OPA
server (opa run --server ...). Check with curl $OPA_URL/health.
TIMEOUT when calling opa_* tools.
The request did not finish within OPA_MCP_HTTP_TIMEOUT_MS (default 15 s).
Either OPA is up but slow, or nothing is answering at OPA_URL and the
connection attempt is being dropped rather than refused, which looks the
same from here. Check OPA_URL and the server's load, or raise the limit.
directory-package-mismatch violation when linting inline source.
Since v0.1.1, the server auto-disables this rule for inline-source calls.
If you see it, you are running an older version -- upgrade to v0.1.1 or
later. To get canonical signal on this rule, lint via paths against the
real on-disk file instead of passing source directly.
Where are the logs?
Default location is <OS-tmpdir>/orygn-opa-mcp.log. That's typically
/tmp/orygn-opa-mcp.log on Linux/macOS or %TEMP%\orygn-opa-mcp.log
on Windows. Set OPA_MCP_LOG_FILE to override, and
OPA_MCP_LOG_LEVEL=debug to widen the firehose.
Development
git clone https://github.com/OrygnsCode/opa-mcp-server.git
cd opa-mcp-server
npm install
npm run devCommon commands:
npm run lint # ESLint
npm run typecheck # tsc --noEmit
npm test # unit tests (Vitest)
npm run test:coverage # unit + coverage report
npm run test:integration # against real opa + regal binaries
npm run build # compile to dist/CI runs lint, typecheck, build, and unit tests on every push and PR
across Ubuntu and Windows on Node 22, 24 and 26, plus macOS on Node 22. Integration
tests run on Linux, and on Windows as a non-required check, against pinned
opa, regal and conftest releases.
For the full contributor workflow (adding tools, naming conventions, logging discipline, release process), see CONTRIBUTING.md.
Versioning & support
This project follows Semantic Versioning. The public surface for SemVer purposes is the set of registered tools, prompts, and resources, their input/output schemas, the recognized environment variables, and the CLI entry point.
Breaking changes will be:
announced in CHANGELOG.md under a new major version,
preceded by at least one minor release with a deprecation warning,
accompanied by a migration note in the release announcement.
Pinned versions of the upstream toolchain (opa and regal) are treated
as part of the build, not as a dependency the operator manages. The
Dockerfile and CI use the same pin; bumps go through
Dependabot or a manual PR.
License
@orygn/opa-mcp is an independent project. It is not affiliated with,
endorsed by, or sponsored by the Open Policy Agent project, the Cloud
Native Computing Foundation, Styra, or Anthropic. "Open Policy Agent"
and "Rego" are trademarks of their respective owners. "Model Context
Protocol" is a trademark of Anthropic, PBC.
Listed in the OPA Ecosystem.
Available Tools
52 toolsconftest_pullConftest pullADestructiveIdempotent
Download Rego policies from an OCI registry or Git repository into a local directory using conftest pull. Use this to hydrate a local policy/ directory before running conftest_test. Requires conftest on PATH or CONFTEST_BINARY set. The policy directory must be inside OPA_MCP_ALLOWED_PATHS. SECURITY: pulled policies are arbitrary Rego source that will be executed by conftest_test. Only pull from registries or repositories you own or explicitly trust -- malicious policy code can use OPA built-ins (http.send, opa.runtime) to exfiltrate data or make outbound network requests when the tests run.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Policy URL to pull. Supported schemes: `oci://registry/repo:tag` (OCI registry), `github.com/org/repo//path` (GitHub subdirectory), `git::https://example.com/repo//path` (generic Git). See https://www.conftest.dev/sharing/ for the full URL syntax. | |
| policy | No | Local directory where the pulled policies will be written. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Omitted, it falls back to `policy` in the working directory of the server process, the conftest convention, which must itself sit inside an allowed root. The directory is emptied before the pull, so do not point it at one holding anything you want to keep. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses that the target directory is emptied before the pull, warns that pulled policies are arbitrary executable Rego with exfiltration/network risks, and notes the external binary dependency and path restrictions. This is substantial value added on top of destructiveHint and readOnlyHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main action and each subsequent sentence covers a distinct aspect: use case, prerequisite, path constraint, and security warning. No filler or redundancy; the security warning earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a side-effectful tool with no output schema, the description covers purpose, prerequisites, destructive side effects, security implications, and path constraints. An agent has everything needed to decide whether to call it and to call it safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, the schema already documents the url schemes and the policy directory fallback and emptying behavior. The tool description doesn't add new parameter-level meaning beyond restating that the policy directory must be inside allowed paths, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: 'Download Rego policies from an OCI registry or Git repository into a local directory using conftest pull.' It identifies the resource, destination, and direction, and it distinguishes itself from the sibling conftest_push by direction and from conftest_test by sequencing ('hydrate ... before running conftest_test').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit usage context: 'Use this to hydrate a local policy/ directory before running conftest_test' and states prerequisites (conftest on PATH or CONFTEST_BINARY, OPA_MCP_ALLOWED_PATHS). It does not explicitly name an alternative to use instead, but the download-vs-push contrast and the sequencing with conftest_test provide clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
conftest_pushConftest pushADestructive
Package the local Rego policy directory as an OCI artifact and push it to a registry using conftest push. Registry credentials must be pre-configured in the host environment (docker login, ORAS keychain, etc.) -- this tool never handles credentials. The policy directory must be inside OPA_MCP_ALLOWED_PATHS. Requires conftest on PATH or CONFTEST_BINARY set.
| Name | Required | Description | Default |
|---|---|---|---|
| policy | No | Path to the local directory containing Rego policies to push. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS) and must exist. Omitted, it falls back to `policy` in the working directory of the server process, the conftest convention, which must itself sit inside an allowed root. | |
| repository | Yes | OCI repository URL to push policies to (e.g. `ghcr.io/my-org/policies:latest`). Registry credentials must already be configured in the host environment (via `docker login`, ORAS keychain, or REGISTRY_AUTH_FILE). This tool does not accept or store registry credentials. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag this as destructive, non-idempotent and open-world, so the safety profile is covered. The description adds genuinely useful context beyond that: it never handles credentials, auth must pre-exist (docker login/ORAS keychain/REGISTRY_AUTH_FILE), and the allowed-paths sandbox constraint. It doesn't discuss overwrite behavior for an existing tag or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the action, followed by the two operational prerequisites. Every sentence earns its place, though it is slightly dense with environment requirements that could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a remote-mutating tool with no output schema, the description covers the essentials an agent needs: authentication expectations, path sandboxing, and the required binary. It omits what a successful push returns and how an existing tag at the same repository is handled, which leaves a small gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents `policy`, `repository` and `v0Compatible` in depth. The description reiterates the allowed-paths and credential constraints but adds no syntax or format detail the schema lacks; baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: packages a local Rego policy directory as an OCI artifact and pushes it via `conftest push`. This is clearly distinguishable from the pull-oriented sibling conftest_pull and from the bundle tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete preconditions for use: credentials must be pre-configured in the host environment, the policy directory must be inside OPA_MCP_ALLOWED_PATHS, and conftest must be on PATH or CONFTEST_BINARY set. It does not explicitly name a when-not or alternative tool, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
conftest_testConftest testA
Evaluate configuration files (Kubernetes manifests, Terraform plans, Dockerfiles, Helm charts, or any YAML/JSON/HCL/TOML/INI) against Rego policies using conftest test. Returns per-file, per-namespace pass/fail/warn results so you can pinpoint exactly which policy rules fired. Requires conftest on PATH or CONFTEST_BINARY set; returns CONFTEST_NOT_FOUND otherwise. Provide config via files (disk paths) or inlineConfig (inline string). Provide policy via policy (disk path) or inlinePolicy (inline Rego source). Omit policy and inlinePolicy to use conftest's default ./policy directory. Policies are executed by conftest and can call OPA built-ins such as http.send.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | Paths to directories from which additional data will be loaded for the Rego policies. Each path must be inside an allowed root. | |
| files | No | Filesystem paths to configuration files to evaluate (YAML, JSON, HCL, Dockerfile, etc.). Each path must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `inlineConfig`. | |
| parser | No | Force a specific parser for all input `files` via conftest's global `--parser` flag, overriding extension-based detection. Useful for files whose extension does not match their format (e.g. parse a `.tfstate` file as `json`). One of: cue, cyclonedx, dockerfile, dotenv, edn, groovy, hcl1, hcl2, hocon, ignore, ini, json, jsonc, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. For `inlineConfig`, prefer `inlineConfigParser`. | |
| policy | No | Path to a directory or file containing Rego policies. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `inlinePolicy`. Omit to let conftest use its default `./policy` directory. | |
| combine | No | Combine all configuration files into a single input document before evaluating. Useful when policies need to inspect relationships across multiple files. | |
| namespace | No | Rego namespace (package name) to test against. Defaults to `main`. Use `allNamespaces: true` to test all discovered namespaces instead. | |
| failOnWarn | No | Return `passed: false` even when only warnings (no hard failures) are present. | |
| inlineConfig | No | Inline configuration content to evaluate (e.g. a Kubernetes manifest as a YAML string). Mutually exclusive with `files`. Defaults to YAML format; set `inlineConfigParser` to override. | |
| inlinePolicy | No | Inline Rego policy source. Written to a temporary directory and passed as `--policy`. The policy should declare `package main` (or match the `namespace` parameter). Mutually exclusive with `policy`. | |
| v0Compatible | No | Read the policies as Rego v0 (`--rego-version v0`), the syntax before OPA 1.0: rules without `if`, `deny[msg] { ... }`. conftest reads v1 by default and refuses such a policy. | |
| allNamespaces | No | Test policies found in all discovered namespaces. Overrides `namespace`. | |
| inlineConfigParser | No | Parser to use for `inlineConfig`. One of: cue, cyclonedx, dockerfile, dotenv, edn, groovy, hcl1, hcl2, hocon, ignore, ini, json, jsonc, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. Defaults to yaml. Ignored when `files` is used (conftest infers the parser from each file's extension, unless `parser` is set). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=false and openWorldHint=true already declared, the description goes further: it discloses the binary prerequisite and failure mode, the mutual-exclusivity rules for policy/config sources, the default ./policy fallback, the per-file/per-namespace pass/fail/warn return shape, and that policies can invoke OPA built-ins like http.send (network egress).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and return contract, then prerequisites and source-selection rules. It is dense and somewhat long for a description, but nearly every sentence carries non-schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, zero-required, no-output-schema tool, the description covers invocation prerequisites, input source selection, defaults, return structure, and execution environment. An agent has enough to call it correctly without opening the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns extra by spelling out the paired sources (`files` vs `inlineConfig`, `policy` vs `inlinePolicy`), the omit-policy default, and the parser/inlineConfigParser split. Most per-parameter detail, however, remains in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb+resource ('Evaluate configuration files') and enumerates the accepted input formats, then names the underlying command. It also distinguishes itself from siblings like rego_test/conftest_verify by naming the conftest execution path and the file-vs-string input model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains when this applies (config files vs Rego policies) and states the prerequisite (`conftest` on PATH or `CONFTEST_BINARY`), plus the CONFTEST_NOT_FOUND outcome. It does not explicitly compare against siblings such as conftest_verify or rego_test, so no exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
conftest_verifyConftest verifyA
Run the test_* rules inside *_test.rego files within a conftest policy directory, verifying that the policies themselves are correct. Equivalent to opa test but using conftest's policy-loading machinery. Returns per-file pass/fail results, and NO_TESTS_FOUND when the directory holds no test rules. Requires conftest on PATH or CONFTEST_BINARY set; returns CONFTEST_NOT_FOUND otherwise.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | Paths to data directories. Each must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). | |
| policy | No | Path to the directory containing both the Rego policies and the `*_test.rego` test files. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Omit to use conftest's default `./policy` directory. | |
| namespace | No | Namespace to verify. Omit to verify all namespaces. | |
| v0Compatible | No | Read the policies as Rego v0 (`--rego-version v0`), the syntax before OPA 1.0: rules without `if`, `deny[msg] { ... }`. conftest reads v1 by default and refuses such a policy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, openWorldHint=true, which say nothing specific), it discloses concrete behavior: per-file pass/fail results, a NO_TESTS_FOUND sentinel for empty test sets, the external `conftest` dependency (PATH or CONFTEST_BINARY), and a CONFTEST_NOT_FOUND failure mode. This is genuinely useful operational context, though it omits what happens if a test itself errors mid-run.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each carrying distinct information (what it runs, the opa-test equivalence, return values, dependencies), with the core purpose front-loaded. It is dense but not padded; the equivalence sentence could be tightened slightly but earns its place by anchoring expectations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly steps in to describe return shape (per-file pass/fail, NO_TESTS_FOUND) and prerequisite/environment failure (CONFTEST_NOT_FOUND). For a 4-param, zero-required tool this is largely complete; the only gap is the unaddressed overlap with the conftest_test sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters (data, policy, namespace, v0Compatible) are already fully documented with constraints and allowed roots. The description adds only a passing reference to the policy directory and does not enrich parameter meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Run the `test_*` rules inside `*_test.rego` files within a conftest policy directory') and clarifies the goal is verifying the policies themselves. It is clear in isolation, but it never distinguishes itself from the very similar sibling conftest_test, so an agent cannot confidently route between them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies usage by framing the tool as 'Equivalent to `opa test` but using conftest's policy-loading machinery', which hints at when to pick it over plain OPA tooling. However, it gives no explicit when-to-use/when-not, and says nothing about how it differs from conftest_test or the rego_test siblings, leaving the closest routing decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mcp_server_infoMCP server infoARead-onlyIdempotent
Return the name, version, and runtime details of this opa-mcp server instance. Use this when you need to confirm which version of opa-mcp is running, or to verify that the OPA, Regal, and Conftest binaries are reachable.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, destructiveHint=false, etc. The description adds value by specifying what the tool returns (name, version, runtime details) and that it checks binary reachability. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences: first states purpose, second provides usage guidance. No wasted words, front-loaded with key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers return values (name, version, runtime details, binary status) adequately. No output schema, but the description provides sufficient context for a simple info tool. Minor gap: 'runtime details' is vague, but overall complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters, and schema coverage is 100%. The description does not need to add parameter info. Baseline for 0 parameters is 4, and the description adds no unnecessary detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns name, version, and runtime details of the opa-mcp server. The verb 'Return' and resource 'opa-mcp server instance' are specific. Among siblings which are mostly OPA/Conftest/Rego manipulation tools, this is the only info tool about the server itself, so differentiation is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states two use cases: confirming the version of opa-mcp and verifying reachability of OPA, Regal, and Conftest binaries. While it doesn't mention when not to use it, the context is clear and no alternatives are needed as the tool is unique among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_bundle_buildBuild OPA bundleADestructiveIdempotent
Build a deployable bundle from policy / data paths using opa build. Output is a .tar.gz archive with optional inline signing. Supports optimization, custom revision strings, and the WASM target.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Policy / data paths to include. Each must be in an allowed root. | |
| bundle | No | Load `paths` as bundle files or root directories (`--bundle`). Implied by `signingKey` and `verificationKey`; set it explicitly to rebuild an existing bundle without signing. | |
| ignore | No | File/directory name patterns to ignore during loading (`--ignore`), e.g. `[".*"]` to skip hidden files. These are name patterns, not filesystem paths. | |
| output | Yes | Output bundle path (typically `*.tar.gz`). Must be in an allowed root. | |
| target | No | Build target (default `rego`; `wasm` compiles to WebAssembly). | |
| optimize | No | Optimization level (0 = none, 2 = aggressive). | |
| revision | No | Bundle revision string written to the manifest. | |
| claimsFile | No | Path to a claims file for inline signing. | |
| signingAlg | No | Signing algorithm (e.g. RS256). | |
| signingKey | No | Path to a PEM private key for signing the built bundle (`--signing-key`). Implies `bundle: true`, which OPA requires for signing. | |
| entrypoints | No | Entrypoint refs (required when `target=wasm` or `optimize > 0`). | |
| pruneUnused | No | Exclude dependents of entrypoints that are not reachable from them (`--prune-unused`). Most useful alongside `entrypoints`. | |
| capabilities | No | Path to a capabilities JSON file. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| v1Compatible | No | Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`). Affects the built bundle's runtime semantics. | |
| verificationKey | No | Path to a PEM public key (or HMAC secret file) used to re-verify an existing signed bundle during the build (`--verification-key`). Implies `bundle: true`, which OPA requires for verification. | |
| verificationKeyId | No | Key ID for verification (`--verification-key-id`, OPA default `default`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=true, so the write/overwrite profile is covered. The description adds useful context about the output artifact and inline signing, but does not disclose that an existing output file may be overwritten or that paths must fall within allowed roots beyond what the schema says.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action and artifact. The trailing capability list is slightly list-like but still earns its place by signalling optimization/signing/WASM support up front.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a build tool with no output schema, the description supplies the key missing piece an agent needs — the returned artifact type and that signing is optional — while the rich schema and annotations carry parameter and safety detail. Routing guidance versus sibling bundle tools is the only notable gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema documents all 17 parameters in depth, so the baseline is 3. The description's mention of optimization, custom revision strings, and the WASM target echoes only a few of those parameters and adds little syntax or format detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Build a deployable bundle from policy / data paths using `opa build`') and names the output artifact (`.tar.gz` archive). This clearly distinguishes it from siblings like opa_bundle_sign and opa_bundle_verify, which operate on an existing bundle rather than producing one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the 'build' framing and the mention of signing/WASM targets, but the description never states when to reach for this tool versus opa_bundle_sign, opa_bundle_verify, or opa_put_policy. No prerequisites (allowed roots, signing key requirements) are stated outside the schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_bundle_signSign OPA bundleADestructiveIdempotent
Sign a bundle directory with opa sign. A directory is signed in place: .signatures.json is written into it and files are recorded as <directory name>/<file>, so the signed directory verifies wherever it is placed as long as its name is unchanged, with opa_bundle_verify or with opa build or opa run --bundle <name> from its parent. An archive is refused: OPA reads the signature from inside it, so a signed archive comes from opa_bundle_build with signingKey. The key is a PEM private key (RSA or ECDSA); for HMAC algorithms pass a file holding the secret. Extra claims such as keyid and scope come from claimsFile. Returns the path written, the algorithm, and the number of files covered.
| Name | Required | Description | Default |
|---|---|---|---|
| bundle | Yes | Path to a bundle directory. Must be inside an allowed root. An archive is refused, since OPA reads the signature from inside it; build a signed archive with `opa_bundle_build` and `signingKey`. | |
| claimsFile | No | Path to a JSON file of extra claims to sign, such as {"keyid": "...", "scope": "..."}. Must be inside an allowed root. | |
| signingAlg | No | Signing algorithm: RS256 (default), RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, HS256, HS384, HS512. | |
| signingKey | Yes | Path to the PEM private key (RSA or ECDSA), or for HMAC algorithms a file holding the secret. Must be inside an allowed root. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing the in-place mutation ('signed in place', `.signatures.json` is written), the naming scheme for recorded files, archive refusal, key-type constraints, and return values. These details align with `destructiveHint=true` and `idempotentHint=true` without contradicting them, and they compensate for the lack of an output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although longer than typical tool descriptions, every sentence carries a distinct piece of information: action, side effects, archive exception, key details, claims, and return value. The most decision-relevant fact (archive refusal and `opa_bundle_build` route) is placed after the core mechanics, which is still well front-loaded and dense without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with no output schema, the description covers the operation, side effects, return payload, parameter specifics, and the important boundary case (archives). The only minor omission is behavior when `.signatures.json` already exists, but the `idempotentHint` annotation covers that, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all four parameters (100% coverage), so the baseline is 3. The description adds value on top by explaining that RSA/ECDSA keys are PEM files while HMAC algorithms expect a file holding the secret, and by spelling out what `claimsFile` should contain. This moves it to a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource pair ('Sign a bundle directory with `opa sign`') and immediately differentiates from siblings by explaining it signs directories, not archives, and that signed archives come from `opa_bundle_build`. It also names `opa_bundle_verify` as the counterpart for verification, so an agent can distinguish it among the bundle-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states that archives are refused and directs agents to `opa_bundle_build` with `signingKey` when a signed archive is needed. It also tells agents where the signed directory can be verified (`opa_bundle_verify`, `opa build`, `opa run --bundle`), making the tool's place in the workflow clear. No ambiguity about when to use this tool versus its bundle siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_bundle_verifyVerify OPA bundle signatureARead-onlyIdempotent
Verify the signature of a signed bundle directory or .tar.gz archive with the public key. OPA has no standalone verify command, so this runs opa build --verification-key into a private temp file that is discarded. A directory is verified by name from its parent, matching how opa_bundle_sign signs it. OPA reads the key, checks the JWT in .signatures.json, compares the scope claim, then checks every file: Rego files by digest before parsing, data files and .manifest by parsed value, so an unparseable data file fails before its digest is compared. Failures return INVALID_BUNDLE with details.reason set to one of signature_invalid, scope_mismatch, file_modified, file_added, file_missing, file_unparseable, unsigned, signatures_malformed, not_a_bundle, bundle_load_error, or unknown when the message is not recognised; the raw output is in details. A key or algorithm OPA cannot use returns INVALID_INPUT. Pass scope exactly as the bundle was signed with. With a single key OPA does not check verificationKeyId against the signature keyid claim. verified: true is returned only when OPA loaded the bundle with its signature intact.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Expected `scope` claim in the signature. Pass exactly the value the bundle was signed with, and nothing if it was signed without one; the failure reason is scope_mismatch otherwise. | |
| bundle | Yes | Path to the signed bundle directory or `.tar.gz` archive. Must be inside an allowed root. | |
| signingAlg | No | Signing algorithm used when the bundle was signed (e.g. `RS256`, `PS256`, `ES256`, `HS256`). Defaults to `RS256`. | |
| v0Compatible | No | Load the bundle as Rego v0 (`--v0-compatible`). A policy written before Rego v1 otherwise fails to load, after the signature and digests have already been checked. | |
| verificationKey | Yes | Path to the PEM file containing the RSA or ECDSA public key, or for HMAC algorithms a file holding the secret. Must be inside an allowed root. | |
| verificationKeyId | No | Name the key is registered under for OPA (`--verification-key-id`, default `default`). With a single key OPA verifies against it regardless of the signature keyid claim, so this rarely needs setting. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior, and the description goes well beyond that by disclosing the temp-file mechanism, the file-by-file verification order, digest-vs-parsed-value differences, failure reason enumerations, and the precise condition for returning `verified: true`. It also surfaces the `verificationKeyId` nuance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries substantive behavioral or edge-case information for a complex tool. It is front-loaded with the core purpose and implementation, then proceeds into verification details and error conditions. Some schema repetition exists, such as the `scope` instruction, but overall it earns its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description thoroughly documents return behavior: `INVALID_BUNDLE` with an enumerated `details.reason`, `INVALID_INPUT` for unusable keys or algorithms, and the exclusive condition for `verified: true`. It also covers failure ordering, v0 compatibility, directory verification convention, and key-ID behavior, making the tool self-sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so a baseline of 3 applies, but the description adds meaningful semantics: `scope` is emphasized as needing to match the signing value exactly, `v0Compatible` is tied to post-signature failure behavior, and `verificationKeyId` is explained as rarely needing to be set with a single key. This enriches the schema without being redundant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb and resource: 'Verify the signature of a signed bundle directory or `.tar.gz` archive with the public key.' It also clarifies the implementation mechanism and the matching relationship to `opa_bundle_sign`, which distinguishes it from general Rego verification siblings like `rego_verify` and `conftest_verify`.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong usage context: it explains that OPA has no standalone verify command, how the verification is performed, what inputs are required, and how `scope` must exactly match the signing value. It does not explicitly name alternative tools or say when not to use this tool, but the guidance is clear enough to invoke correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_compile_queryCompile (partially evaluate) a query on OPAARead-onlyIdempotent
Send a query to the OPA server's /v1/compile endpoint for partial evaluation. Returns the residual query -- what remains after substituting in everything that's known.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Optional partial input document. | |
| query | Yes | Rego query to compile, e.g. "data.rbac.allow == true". | |
| unknowns | No | Refs to treat as unknown (default: ["input"]). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and idempotentHint=true. The description adds value by specifying the exact HTTP endpoint and explaining the concept of partial evaluation (substituting knowns). This provides behavioral context beyond annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences efficiently deliver the action and result. No extraneous text. The first sentence is front-loaded with the verb 'compile' and endpoint, making it immediately actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's core behavior and return value (residual query) without an output schema. It assumes familiarity with OPA concepts but is sufficient for an agent. Could add more on use cases or prerequisites, but is adequate for the complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear descriptions for all three parameters. The tool description reinforces the purpose of partial evaluation but does not add new parameter-specific details beyond the schema. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool sends a query to the OPA server's /v1/compile endpoint for partial evaluation and returns the residual query. This distinguishes it from evaluation tools like rego_eval or opa_query_decision, showing a specific verb and resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool vs alternatives such as rego_eval or opa_query_decision. It only mentions partial evaluation but gives no guidance on scenarios or exclusions, leaving the agent to infer usage context from the tool name and siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_configOPA configurationARead-onlyIdempotent
Return the running OPA server configuration from GET /v1/config. OPA drops the credentials block but returns services.*.headers verbatim, which is the ordinary place to put an API key or a bearer token, so those values are redacted here and the header names kept.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses non-obvious behavior well beyond the annotations: OPA drops the `credentials` block, returns `services.*.headers` verbatim, and redacts header values while keeping header names. This is exactly the kind of behavioral context that helps an agent anticipate the returned data and security implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose and followed by a high-value behavioral caveat. Every clause earns its place; there is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple zero-parameter read operation. The description states what is returned, where it comes from, and the important redaction behavior. Annotations already convey read-only and idempotent safety. No critical information is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema coverage is 100%, so there are no parameter semantics for the description to clarify. Per the rubric, a zero-parameter tool gets a baseline of 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and a precise resource ('the running OPA server configuration from `GET /v1/config`'). This clearly identifies what the tool does and separates it from sibling tools like opa_status or opa_health, which concern server health rather than configuration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The use case is implied: if an agent needs the running OPA server configuration, this is the tool. However, the description does not explicitly state when to prefer this over alternatives or mention any exclusions, so guidance is present only by inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_delete_dataDelete a data document from OPAADestructive
Remove a document from OPA's data store at the given path. A path is read as dotted (users.alice) unless it contains a slash, in which case slash is the only separator (users/alice), so a key such as example.com is addressable as hosts/example.com. Pass segments instead when a key contains both. OPA responds with 204 No Content on success; if no document exists at the path, OPA returns 404 which is mapped to DATA_NOT_FOUND. Root-path deletion (/v1/data/ itself) is intentionally excluded -- supply at least one path segment.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Data path to delete, e.g. "users.alice" or "users/alice". Must be at least one segment deep. | |
| segments | No | Path as literal key segments, e.g. ["labels", "app.kubernetes.io/name"]. Use instead of `path` when a key contains a dot or a slash. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (destructiveHint=true, idempotentHint=false), the description discloses the 204 success response, the 404-to-DATA_NOT_FOUND mapping, and the intentional root-path exclusion. These behaviors directly inform an agent about success, failure, and edge cases, which is exactly the kind of context annotations alone cannot provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense but every sentence earns its place: the core action, path syntax rules, fallback parameter guidance, and edge-case behavior are all stated with no filler. The most important context is front-loaded and the formatting is easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter destructive operation with no output schema, the description is complete: it covers success codes, error mapping, path constraints, and the root-path edge case. The annotations already mark the destructive nature, and the description fills the remaining behavioral gaps an agent would need to safely invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already covers 100% of parameters, the description adds crucial semantics: dotted vs slash-only path parsing, how to address keys containing dots or slashes, and when to switch from `path` to `segments`. This resolves ambiguous inputs that the schema descriptions only partially convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Remove') with a clear resource ('document from OPA's data store') and the path-based scope. It naturally distinguishes itself from sibling tools like opa_delete_policy by explicitly targeting the data store rather than policy.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational context: it explains when to use `path` vs `segments`, notes the root-path deletion exclusion, and requires at least one segment. It does not explicitly compare itself to alternative data-management tools like opa_patch_data or opa_put_data, but the conditional guidance is strong and the tool's purpose is unmistakable among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_delete_policyDelete OPA policyADestructive
Delete a policy by ID from the running OPA server.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Policy ID to delete. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, making the delete behavior clear. The description adds minimal extra context ('from the running OPA server') but does not disclose potential side effects, authentication needs, or constraints beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no wasted words. Every word is necessary and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter schema and no output schema, the description is mostly complete. However, it could mention error handling (e.g., policy not found) or that deletion is permanent, which would raise completeness to 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with 'Policy ID to delete.' in the parameter description. The tool description adds no further meaning, meeting the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action 'Delete', the resource 'a policy', and specificity 'by ID from the running OPA server'. This distinguishes it from sibling tools like opa_get_policy or opa_delete_data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives (e.g., opa_put_policy to update) or prerequisites like ensuring the policy exists. The description only states the action without contextual usage advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_execBatch-evaluate OPA policy against input filesA
Evaluate a policy decision against one or more input files using opa exec --format=json. Unlike rego_eval (single input), opa exec processes every file independently and returns a per-file result -- ideal for CI pipelines that check many config files against a policy in one call. Supply bundle for a bundle, or dataPaths for plain .rego, JSON and YAML files and directories, which are loaded as opa eval --data loads them; the two are mutually exclusive. Each file that fails evaluation appears in results with an error field rather than a result field. Set one of fail/failDefined/failNonEmpty to turn the call into a CI gate: the result then reports failed: true (instead of erroring) when the gate condition is met.
| Name | Required | Description | Default |
|---|---|---|---|
| fail | No | CI gate: report `failed: true` when any decision is undefined or errors. Mutually exclusive with `failDefined` and `failNonEmpty`. | |
| bundle | No | Path to an OPA bundle directory or `.tar.gz` archive to load as the policy source. Mutually exclusive with `dataPaths`. | |
| timeout | No | Per-exec evaluation timeout as a Go duration, e.g. `"30s"` or `"5m"`. Still bounded by the server subprocess timeout (OPA_MCP_TIMEOUT_MS). | |
| decision | Yes | The policy entrypoint to evaluate for each input, e.g. `"authz/allow"`. `opa exec` names a decision by slash-separated path with no `data.` prefix; the Rego reference forms (`data.authz.allow`, `authz.allow`) are accepted here and converted, because passing one straight through leaves every file undefined. | |
| dataPaths | No | Policy and data files or directories, loaded the way `opa eval --data` loads them: a `.rego` file as a module, a JSON or YAML file merged into the data root, a directory recursively, so every JSON and YAML file in it is data and must parse. One difference: a bundle archive (`.tar.gz`) inside a directory is not loaded, and `warnings` names it. A bundle given here directly (an archive, or a directory holding a `.manifest`) is loaded as a bundle; bundles and plain paths cannot be mixed. To load a directory as a bundle, reading only its `.rego` files and those named data.json, data.yaml or data.yml, pass it as `bundle`. Mutually exclusive with `bundle`. | |
| inputPaths | Yes | One or more JSON/YAML input file paths, or a directory containing input files. OPA evaluates each file independently. Every path must be inside an allowed root. | |
| failDefined | No | CI gate: report `failed: true` when any decision is defined or errors. Use when a defined result means a violation. Mutually exclusive with `fail` and `failNonEmpty`. | |
| failNonEmpty | No | CI gate: report `failed: true` when any decision result is non-empty or errors. Mutually exclusive with `fail` and `failDefined`. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| v1Compatible | No | Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are sparse (readOnlyHint=false, openWorldHint=true) so the description carries real weight, and it delivers: mutual exclusivity of bundle/dataPaths, per-file failure reporting ('appears in `results` with an `error` field rather than a `result` field'), and the gating semantics where errors become `failed: true` instead of throwing. Note the description frames the operation as pure evaluation while readOnlyHint=false implies otherwise, but the description never claims a read-only guarantee, so this is conservatism rather than a contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences with no filler, ordered purpose → alternative → parameter relationships → gate behavior, so the most decision-relevant information is front-loaded. It runs long, but every clause maps to a real selection or invocation decision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description covers the essentials: which parameters are mutually exclusive, what the per-file result surface looks like (result vs error), and what the gate flags change. It stops short of describing the full success-result shape per file, which is the only remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes beyond by explaining the relationship between `bundle` and `dataPaths` (mutually exclusive, loaded as `opa eval --data` would) and why the `decision` path form matters ('passing one straight through leaves every file undefined'). That is semantic framing the schema alone does not establish.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Evaluate a policy decision against one or more input files using `opa exec --format=json`') and immediately scopes it against the closest sibling: 'Unlike `rego_eval` (single input), `opa exec` processes every file independently.' An agent can distinguish this from the many other eval tools without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative (`rego_eval`) and the condition that selects this tool instead ('processes every file independently ... ideal for CI pipelines that check many config files against a policy in one call'). It also gives when-to-use guidance for the gate flags ('Set one of `fail`/`failDefined`/`failNonEmpty` to turn the call into a CI gate').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_get_dataRead data from OPAARead-onlyIdempotent
Read a path from OPA's data hierarchy. A path is read as dotted (users.alice) unless it contains a slash, in which case slash is the only separator (users/alice), so a key such as example.com is addressable as hosts/example.com. Pass segments instead when a key contains both.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Data path under `data.`, e.g. "users" or "users/alice". | |
| segments | No | Path as literal key segments, e.g. ["labels", "app.kubernetes.io/name"]. Use instead of `path` when a key contains a dot or a slash. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds valuable behavioral detail about path interpretation: dotted notation versus slash-only separator, and how a key containing a dot can still be addressed. This goes beyond what annotations and schema alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tightly written sentences with no filler. The core action is front-loaded, and the necessary path-format nuances are packed efficiently into the remaining sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity read tool with strong annotations, the description is nearly complete. It covers the trickiest part: path formatting and segments selection. A minor gap is that it does not state what happens when neither `path` nor `segments` is provided, even though the schema allows zero required parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, the baseline is 3, but the description substantially enriches parameter understanding. It clarifies the dotted-path rule, the slash-only fallback, the `example.com` addressing case, and the exact condition for using `segments` instead of `path`. This resolves real ambiguity in how to invoke the tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Read a path from OPA's data hierarchy,' which names a specific verb, resource, and scope. This clearly differentiates it from siblings like opa_get_policy (policies) and opa_query_decision (decision evaluation) by targeting the data hierarchy specifically.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong internal guidance on when to use `path` vs `segments`, but it never names alternative tools or states when this tool should be preferred over opa_get_policy or opa_query_decision. Tool-selection context is implied by 'data hierarchy' but not made explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_get_policyGet OPA policy by IDARead-onlyIdempotent
Fetch a single policy by ID from the running OPA server. Returns the Rego source; the parsed AST is omitted unless asked for, since it is roughly forty times the size of the source it came from. Use rego_parse_ast on the source when an AST is what's wanted.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Policy ID, e.g. "rbac" or "policies/auth/main". | |
| includeAst | No | Include OPA's parsed AST alongside the source. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the bar for added context is lower. The description adds real behavior: the tool returns Rego source, omits the AST by default, explains the size tradeoff, and notes the includeAst alternative. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, all substantive, with the main purpose in the first clause. No filler or duplication of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-required-parameter read tool, the description covers what the caller gets (Rego source), the optional behavior (includeAst), and the alternative for AST. Annotations cover safety and idempotency, and schema covers parameters, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are fully documented; the description adds little beyond what the schema already provides. The mention that AST is omitted 'unless asked for' aligns with includeAst's schema description, so no additional compensation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb+resource: 'Fetch a single policy by ID from the running OPA server.' It clearly scopes to one policy, distinguishes from list/put/delete siblings, and differentiates from rego_parse_ast by stating this returns Rego source and AST is optional.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states that the AST is omitted unless asked and directs the agent to use `rego_parse_ast` when an AST is wanted, giving a concrete when-not. It also implies the primary use case—getting the Rego source for one policy—without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_healthOPA health checkARead-onlyIdempotent
Hit the OPA /health endpoint. A server that answers reports { healthy: true } on 200 and { healthy: false } with OPA's own reason otherwise, so an unactivated bundle is a health result rather than a tool error. OPA_UNREACHABLE means the server could not be reached at all. Supports bundles and plugins query flags to require those subsystems to also be healthy.
| Name | Required | Description | Default |
|---|---|---|---|
| bundles | No | Require bundle plugin to be healthy as well. | |
| plugins | No | Require all plugins to be healthy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safe-read profile (readOnlyHint, idempotentHint, non-destructive), so the description's job was to add behavioral depth beyond that, and it delivers: the exact endpoint, 200-vs-otherwise result semantics, the key gotcha that an unactivated bundle yields { healthy: false } rather than a tool error, and the OPA_UNREACHABLE failure mode. These are precisely the interpretation cues an agent needs and cannot derive from annotations or the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, roughly 70 words, with no filler. The endpoint is front-loaded, followed by result interpretation, the unreachable edge case, and finally the flags — a logical order where every sentence earns its place. Nothing is redundant with the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-required-param, read-only health check with no output schema, the description is fully sufficient: it names the endpoint, defines both success and failure result shapes, covers the edge cases (unactivated bundle, unreachable server), and documents both optional flags. There is nothing an agent needs in order to call this tool correctly that is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — both bundles and plugins already carry adequate descriptions. The description's phrase 'query flags to require those subsystems to also be healthy' adds a small amount of meaning by tying the booleans to the subsystem-health concept, which aligns with and slightly reinforces the schema. Since the schema does the heavy lifting, the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the specific resource (`/health` endpoint) with a clear verb ('Hit'), and then defines the expected response semantics. This makes the tool immediately distinguishable from the many siblings in the namespace, especially opa_status and opa_config, without needing to open their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys useful context about when to use the tool — checking whether the OPA server (and optionally its subsystems) is healthy — and clarifies that an unactivated bundle appears as a health result rather than a tool error, which affects result interpretation. However, it never explicitly names alternatives or gives when-to-use / when-not-to-use conditions, so routing among overlapping siblings like opa_status and opa_config is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_list_policiesList OPA policiesARead-onlyIdempotent
List policies registered on the running OPA server. Returns the policy IDs and a count. Set includeSource for the Rego text of every policy, or includeAst for the parsed AST of every policy; both are off by default because either one pushes a list of any real size past the response cap.
| Name | Required | Description | Default |
|---|---|---|---|
| includeAst | No | Include each policy's parsed AST. Off by default; it is roughly forty times the size of the source and will exceed the response cap on all but the smallest servers. | |
| includeSource | No | Include each policy's Rego source. Off by default: fetch one policy with `opa_get_policy` rather than every policy at once. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile comprehensively (readOnlyHint=true, idempotentHint=true, openWorldHint=true, destructiveHint=false), so the bar for the description is lower. The description adds genuine behavioral value beyond annotations by disclosing the response-cap behavior: enabling either include flag can cause list responses to exceed the cap. This is exactly the kind of operational trait an agent needs to anticipate failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler. The first sentence front-loads the action and return value; the second handles the optional parameters and the reason for the defaults. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple listing tool with 0 required parameters, rich annotations, and no output schema, the description is nearly complete: it states the return value at a useful level ('policy IDs and a count') and explains both flags. It could marginally improve by describing the response envelope or ordering, but nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with unusually rich per-parameter descriptions (size ratios, response-cap warnings, alternative-tool routing), which sets the baseline at 3. The description adds meaning on top by distinguishing the two flags at a semantic level — 'Rego text' vs 'parsed AST' — and stating the shared default-off behavior and its rationale, which is not fully redundant with the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — 'List policies registered on the running OPA server' — and goes beyond that to specify the return value ('policy IDs and a count'). The phrase 'running OPA server' clearly differentiates this from the many rego_* sibling tools that operate on static policy files, and from opa_get_policy/opa_put_policy/opa_delete_policy which target individual policies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: use this to enumerate registered policies, and the optional include flags are discouraged by default because they 'push a list of any real size past the response cap.' This effectively tells an agent when NOT to set the flags. It does not explicitly name opa_get_policy as the alternative for fetching a single policy's source in the description body — that routing lives in the schema — so it stops just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_patch_dataPatch data on OPAADestructive
Apply a JSON Patch (RFC 6902) to the data document. Each operation is { op, path, value? }. Omit both path and segments to patch the root of the data hierarchy, which is how a whole new top-level document is added.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Data path the patch is applied to. | |
| segments | No | Path as literal key segments, e.g. ["labels", "app.kubernetes.io/name"]. Use instead of `path` when a key contains a dot or a slash. | |
| operations | Yes | Array of JSON Patch operations. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a destructive, non-idempotent write operation. The description adds useful behavioral context by explaining the operation format and that omitting path and segments patches the root to add a new top-level document. It does not go into further side effects, but the annotation covers the main destructive risk.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no wasted words. It front-loads the core action, then gives the operation shape, then handles the important root-patch special case. Each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter tool with annotations covering the destructive nature and a schema covering all parameters, the description provides the remaining key context: how operations are structured and how to target the root. There is no output schema, but return-value details are not critical for invoking this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value beyond the schema by clarifying the JSON Patch operation shape and the special root-patching behavior when both path and segments are omitted. This is meaningful parameter-level guidance an agent would not get from the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action: applying an RFC 6902 JSON Patch to the OPA data document. It names a specific verb and resource and is distinct from sibling tools like opa_put_data and opa_delete_data, though it does not explicitly differentiate itself from them in the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when this tool is useful by defining it as the JSON Patch mechanism for data, and it gives a concrete usage tip about omitting path/segments to patch the root. However, it does not explicitly state when to use this tool instead of alternatives such as opa_put_data or opa_delete_data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_put_dataWrite data to OPAADestructiveIdempotent
Write or replace a value at the given data path. Body is sent as JSON. A path is read as dotted (users.alice) unless it contains a slash, in which case slash is the only separator (users/alice), so a key such as example.com is addressable as hosts/example.com. Pass segments instead when a key contains both.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Data path to write to. | |
| value | No | JSON value to store at this path. | |
| segments | No | Path as literal key segments, e.g. ["labels", "app.kubernetes.io/name"]. Use instead of `path` when a key contains a dot or a slash. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive and idempotent hints; the description adds non-obvious runtime behavior: the body is JSON, path separator parsing switches between dots and slashes, and dot-containing keys can be addressed via slash-separated paths. This is meaningful context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: purpose, body format, separator rule, and segments fallback. The most important verb-first statement is front-loaded and the paragraph is dense without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tricky path-encoding behavior is fully explained, and annotations cover the destructive/idempotent safety profile. There is no output schema and no response description, but for a write operation the essential calling requirements are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description elevates it by explaining how `path` is parsed, why `hosts/example.com` works, and when `segments` is the right parameter. It adds practical meaning not fully present in the schema's field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Write or replace a value') on a specific resource (OPA data path), which clearly distinguishes it from siblings like opa_patch_data and opa_delete_data. The 'replace' wording communicates full overwrite rather than merge or delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives useful in-tool guidance for choosing path versus segments, but it never addresses when to use opa_put_data instead of opa_patch_data or opa_delete_data. Tool-vs-alternative selection is therefore left mostly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_put_policyUpload or replace OPA policyADestructiveIdempotent
Upload a Rego policy under the given ID. Replaces any existing policy with that ID. The policy is uploaded as raw text/plain -- OPA parses it on the server side.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Policy ID to create or replace. | |
| source | Yes | Rego source. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive and idempotent behavior. The description adds that the policy is uploaded as raw text/plain and parsed server-side, and that it replaces any existing policy with that ID, providing useful behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no redundant information. It is concise and front-loaded with the key action. Could potentially be structured as a brief paragraph but still efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema, the description covers core behavior (replace, raw text). However, it does not mention return values or error conditions, which would be helpful for completeness given the tool's destructive nature.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions already define 'id' and 'source' adequately. The description adds that the source is raw text/plain, which is helpful but not extensive. With 100% schema coverage, the description does not significantly enhance parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Upload' and resource 'Rego policy' with a given ID. It distinguishes from sibling tools like opa_get_policy and opa_delete_policy by specifying the upload/replace action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives such as opa_put_data or opa_bundle_build. There is no mention of prerequisites or context where this tool is preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_query_decisionQuery OPA decisionARead-onlyIdempotent
Evaluate a decision against the running OPA server. POSTs to the data path with {input} and returns whatever the rule produces. Use this to ask the server "given this input, what does data.X.allow say?"
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Decision path under `data.`, e.g. "rbac/allow" or "rbac.allow". | |
| input | No | Input document to evaluate against. | |
| explain | No | Include a trace at the requested level. | |
| metrics | No | Include metrics in the response. | |
| segments | No | Path as literal key segments, e.g. ["labels", "app.kubernetes.io/name"]. Use instead of `path` when a key contains a dot or a slash. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, idempotent, and non-destructive. The description adds valuable behavioral context by specifying the POST method, the data-path endpoint, and that the response is 'whatever the rule produces'. It does not detail error or undefined-rule behavior, but the annotations lower the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted words. It front-loads the action and endpoint, then gives a concrete example in the second sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the phrase 'returns whatever the rule produces' gives useful response expectations, and annotations cover the safety profile. The need to provide a path or segments is implied but not explicit, which is a minor gap given the schema hints.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all five parameters with clear descriptions. The description reinforces the meaning of `path` and `input` through the data.X.allow example, but it does not add significant meaning beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Evaluate'), a specific resource ('the running OPA server'), and the mechanism ('POSTs to the data path'). The quoted example, 'given this input, what does data.X.allow say?', clearly differentiates this from local evaluation siblings like rego_eval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for when to use this tool: querying a running OPA server with an input document. It implicitly distinguishes from local rego evaluation tools, but it does not explicitly name alternatives or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
opa_statusOPA statusARead-onlyIdempotent
Return the running OPA server configuration via GET /v1/config. Returns the same underlying document as opa_config but presented under a status key as a convenience for agents that want to check "what is running" rather than "what was the server configured with". The response includes bundle settings, decision-log settings, and plugin configuration as OPA reported them at startup. Service header values are redacted, since OPA returns them verbatim and a header is the ordinary place to put an API key.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/idempotentHint annotations, the description discloses meaningful behavioral details: the response reflects startup-reported configuration, includes bundle/decision-log/plugin settings, and service header values are redacted because they may contain API keys. This adds genuine transparency beyond what structured annotations already convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first states the action and endpoint, the second clarifies the difference from a sibling tool, and the third covers response contents and a security-relevant redaction. The description is front-loaded and compact with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although there is no output schema, the description compensates by enumerating response categories, clarifying the relationship to opa_config, and warning about redacted header values. For a zero-parameter read-only status tool, this is sufficient context for an agent to invoke it correctly and interpret its result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so schema coverage is complete by definition and the description need not explain parameters. It still adds useful context about what the returned configuration document contains and the redaction policy, which is more than the empty schema provides. Baseline 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Return the running OPA server configuration via GET /v1/config') and precisely distinguishes this tool from its sibling opa_config by noting the 'status' key presentation and the intent to check 'what is running' vs 'what was configured'. This gives an agent a clear, unambiguous purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names the alternative tool opa_config and states the selection criterion: use this when the agent wants 'what is running' rather than 'what was the server configured with'. This is direct routing guidance with no ambiguity about when to prefer this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_benchBenchmark Rego queryA
Benchmark a Rego query against a policy + input with opa bench. Returns statistical timing data: iterations, ns/op, and allocation counts. Use this to spot slow rules.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of times to repeat the benchmark (`--count N`). Defaults to OPA's built-in default of one. Above one, every repetition is returned in `runs`, `fastest` indexes the one the top-level figures come from, and `raw` is omitted since that document is in `runs`. | |
| input | No | Inline input document. | |
| paths | No | Policy / data paths to load. Each must be in an allowed root. | |
| query | Yes | Rego query to benchmark. | |
| inputPath | No | Path to a JSON input file. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=true, so the description carries most of the behavioral load. It discloses the underlying mechanism (`opa bench`) and the shape of the result (iterations, ns/op, allocation counts), which is genuinely useful for an agent that has no output schema. It does not mention execution cost, timeouts, or the fact that benchmarking repeatedly executes the policy.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences that are front-loaded with the action, then the return shape, then the reason to use it. No filler and nothing repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must say something about returns, and it does summarize the statistical fields. The count>1 behavior (runs/fastest, omitted raw) is only explained in the schema's count parameter, leaving the description slightly thin for an agent sizing up results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% across all six parameters, so the schema already documents query, input, paths, count, inputPath, and v0Compatible in detail. The description adds no parameter-level meaning beyond what the schema supplies, which is the baseline-3 case.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (benchmark) and resource (a Rego query against a policy + input), names the underlying command (`opa bench`), and reports what comes back (iterations, ns/op, allocation counts). It does not explicitly name the nearest sibling (rego_eval_with_profile), so an agent must infer the distinction itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use this to spot slow rules" gives a motivating use case, which implies the performance-investigation context. There is no explicit when-not guidance and no mention of alternatives such as rego_eval_with_profile, so the agent must decide between them on its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_capabilitiesOPA capabilitiesARead-onlyIdempotent
Return OPA capabilities -- the available builtins, future keywords, features, and WASM ABI versions. With current: true, returns the running OPA's capabilities. With version: "v1.19.0", returns those of a specific version. With neither, lists available named versions. By default (names_only: true), returns only builtin names and count to stay within response size limits. Pass builtins: [...] for the full type signatures and documentation of a few named builtins; names_only: false returns every full record, which needs OPA_MCP_MAX_RESPONSE_BYTES raised above its default.
| Name | Required | Description | Default |
|---|---|---|---|
| current | No | Print the capabilities of the currently installed OPA. Mutually exclusive with `version`. | |
| version | No | A specific OPA capabilities version (e.g. "v1.21.0"). When neither flag is set, lists available versions. | |
| builtins | No | Return the full record (type signature, documentation, metadata) for up to 100 builtin names, exact matches only. `matched` counts the records returned and names not found are listed under `missing`. When the records would not fit the response cap the tool returns OUTPUT_TOO_LARGE rather than a truncated result; ask for fewer names. Do not combine with `names_only: true`, which asks for the opposite. | |
| names_only | No | When true, or omitted, return only builtin names, count, future keywords, and features. The full payload for every builtin is larger than the default response cap (OPA_MCP_MAX_RESPONSE_BYTES), so `names_only: false` on its own needs that cap raised; use `builtins` to get full records for a few names instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds genuinely useful behavior beyond that: the default behavior (`names_only: true`), the response-size limitation rationale, the need to raise OPA_MCP_MAX_RESPONSE_BYTES for full records, and the OUTPUT_TOO_LARGE risk implied by the schema. Nothing contradicts the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then progresses logically through parameter modes, defaults, and caveats. Every sentence carries distinct information, and the length is justified by the four-parameter mode matrix. There is no filler or redundant restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description carries the burden of return-value clarity and does it well: it names the returned categories, explains the `count` and `matched`/`missing` behavior via the schema's `builtins` description, and warns about response-size limits. Minor gap: it does not describe the exact JSON shape of the non-builtin sections (e.g., fields for future keywords/features/WASM versions), but enough is stated for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds value beyond the schema by explaining the parameter interplay: the mutual exclusivity implied for `current`/`version`, the effect of omitting both, and the relationship between `builtins` and `names_only`. The schema already contains detailed per-parameter text, so the description does not need to repeat it all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Return OPA capabilities' and enumerates exactly what is included ('available builtins, future keywords, features, and WASM ABI versions'). This clearly distinguishes it from the rego evaluation/parsing siblings, which operate on policies rather than OPA runtime capability metadata.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong conditional guidance for each invocation mode ('With current: true...', 'With version: "v1.19.0"...', 'With neither...') and explains when to use `builtins` vs `names_only: false` based on response-size constraints. It does not explicitly name sibling alternatives, but no sibling tool offers this capability, so the mode-level guidance effectively covers when to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_checkCheck RegoARead-onlyIdempotent
Type-check Rego with opa check. Returns { valid: true, errors: [] } on success, or a list of structured diagnostics with file/line locations on failure. Provide either source for inline checking or paths for file/directory checking.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Filesystem paths to check. Each path must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). | |
| bundle | No | Load `paths` as bundle files or root directories (`--bundle`). Only valid with `paths`, not inline `source`. | |
| source | No | Inline Rego source. Mutually exclusive with `paths`. | |
| strict | No | Enable strict mode -- fail on unused vars, deprecated builtins, etc. | |
| maxErrors | No | Maximum number of errors to collect before `opa check` aborts compilation (`--max-errors`, OPA default 10). Raise it to surface more diagnostics from a badly broken policy in a single pass. | |
| schemaDir | No | Schema directory for input/data validation. | |
| capabilities | No | Path to a capabilities JSON file restricting allowed builtins. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds real value beyond that: it documents the return shape ('{ valid: true, errors: [] }') and the failure mode (structured diagnostics with file/line locations), which matters given no output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with the core action, the return contract, and the input-mode choice front-loaded in that order. No filler or restated boilerplate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly supplies the return contract, and annotations cover the safety profile while the schema covers all parameters. It is nearly complete; only the lack of sibling routing (check vs lint) leaves a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every one of the 8 parameters is already documented in the schema, setting the baseline at 3. The description's only parameter-level addition is the source/paths mutual exclusivity, which the schema already states, so it adds little beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Type-check Rego with `opa check`') plus the exact underlying command, which lets an agent separate it from rego_lint and rego_parse_ast. It does not explicitly name or contrast those siblings, so it falls short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys the source-vs-paths usage pattern ('Provide either `source` for inline checking or `paths` for file/directory checking'), which is useful. However, it gives no guidance on when to reach for rego_check versus rego_lint, rego_compile_query, or rego_migrate_v1, so usage is only implied by the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_check_schemaCheck Rego against a JSON SchemaARead-onlyIdempotent
Validate that a Rego policy's input.* field references are consistent with a JSON Schema using opa check --schema. Every field the policy reads from input must exist in the schema; mismatches surface as rego_type_error diagnostics with file/line locations. Returns { valid: true, errors: [] } when all references match the schema, or { valid: false, errors: [...] } with structured diagnostics when they do not. Accepts the schema inline (pass the schema output of rego_infer_input_schema directly as inlineSchema) or as a path to a JSON Schema file on disk, or to a schema directory when the policy declares schemas: annotations (schemaPath). Provide source for inline Rego or paths for file/directory checking.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Filesystem paths to policy files or directories to validate. Each path must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `source`. | |
| source | No | Inline Rego source to validate against the schema. Mutually exclusive with `paths`. | |
| strict | No | Enable strict mode -- also fail on unused variables, deprecated builtins, and other non-fatal issues in addition to schema violations. | |
| schemaPath | No | Path to a JSON Schema file on disk to use for `input` validation, or to a schema directory when the policy carries `# METADATA` / `schemas:` annotations naming files in it (opa reads a directory only through those). Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `inlineSchema`. | |
| inlineSchema | No | JSON Schema (draft-07) object describing the expected shape of the `input` document. Mutually exclusive with `schemaPath`. Accepts the `schema` field from `rego_infer_input_schema` output directly. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly/idempotent/non-destructive), and the description adds real value: it names the failure mode (rego_type_error diagnostics with file/line), and gives the exact return shape `{valid, errors}`. It doesn't discuss rate limits or path-root rejection errors beyond what the schema already says.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but well ordered: purpose first, then diagnostic/return behavior, then the schema-input modes, then source-vs-paths. Every sentence carries information, though the final sentence slightly stacks multiple mode descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter, nested-object tool with no output schema, the description supplies the return contract and mode semantics the agent needs. Minor gaps remain around ordering when both none of source/paths are supplied, but overall it is complete enough to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds integration meaning beyond the schema: it tells the agent it can pass `rego_infer_input_schema`'s `schema` output straight through as `inlineSchema`, and clarifies the directory-vs-file semantics of `schemaPath`.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+mechanism: validate a Rego policy's `input.*` references against a JSON Schema via `opa check --schema`. This clearly distinguishes it from siblings like rego_check, rego_lint, and rego_infer_input_schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the two schema-input modes (inline via rego_infer_input_schema output, or path/directory) and the source-vs-paths choice, giving clear usage context. It does not, however, explicitly state when to prefer this over rego_check or rego_verify, so no full when-not framing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_compile_queryPartially evaluate a Rego queryA
Run partial evaluation on a query -- substitute known values and return the residual policy. Defaults unknowns to ["input"] (treat input as unknown), so the residual encodes "given input X, this is what would have to be true." Use this for offline policy slicing or pre-computing decision sets.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Inline input document. | |
| paths | No | Policy / data file or directory paths. Each must be inside an allowed root. | |
| query | Yes | Rego query to evaluate, e.g. "data.example.allow". | |
| source | No | Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression. | |
| partial | No | Run partial evaluation rather than full evaluation. | |
| unknowns | No | Refs to treat as unknown during partial evaluation. | |
| inputPath | No | Path to a JSON input file. Mutually exclusive with `input`. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| strictBuiltinErrors | No | Treat builtin errors as fatal instead of returning undefined. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=true; the description goes beyond them by disclosing the default of `unknowns` (`["input"]`) and the meaning of the residual output. It does not address the surprising non-read-only annotation for what reads as a pure computation, but it adds genuine behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core operation and followed immediately by the key default and the intended use case. No filler; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 9 params, 100% schema coverage and no output schema, the description covers purpose, the critical default, and the use case well. Return values are described only at a high level ('residual policy'), which is acceptable given the absence of an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value the schema does not: the default value and interpretation of `unknowns` and what the residual encodes, which is the single most important parameter behavior for this tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a precise operation ('Run partial evaluation on a query'), explains the mechanic (substitute known values, return the residual policy), and contrasts implicitly with plain evaluation via the `partial` semantics. It does not explicitly name a sibling (e.g. rego_eval or opa_compile_query), so the agent must infer differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete use cases -- 'offline policy slicing or pre-computing decision sets' -- which is clear when-to-use guidance. It stops short of stating when NOT to use it or naming an alternative evaluation tool, so it is not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_coverage_gapsRego test coverage gapsA
Run opa test --coverage and return a per-file breakdown of uncovered line ranges. Identifies which rules or branches are not yet exercised by tests. Files are sorted by coverage ascending so the worst-covered files appear first. Use threshold to limit the report to files below a target coverage percentage.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Test directories or files. opa test looks for *_test.rego siblings of source files. | |
| threshold | No | Report only files below this coverage percentage (0-100). When omitted, all files with uncovered ranges are reported. | |
| runPattern | No | Run only tests whose names match this regex. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=true, so the safety profile is at least partly covered. The description adds useful behavioral detail (per-file breakdown, ascending sort order) but says nothing about cost, side effects of executing test code, or prerequisite test files, which matters given readOnlyHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences, front-loaded with the core action and outcome, then sort behavior and the threshold hint. No filler or redundancy, though the last sentence slightly duplicates the schema's threshold text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does its job by characterizing the return value (per-file uncovered line ranges, sorted worst-first). It omits what happens when no tests exist or when paths contain no matching *_test.rego files, but it is otherwise sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters, including threshold and v0Compatible. The description restates threshold semantics and the sort behavior but adds no format, syntax, or edge-case detail beyond what the schema provides. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: runs `opa test --coverage` and returns per-file uncovered line ranges, identifying unexercised rules/branches. Clear to an agent. However, it never distinguishes itself from close siblings like rego_test or rego_eval_with_coverage, leaving differentiation implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only usage guidance is 'Use threshold to limit the report to files below a target coverage percentage', which is parameter mechanics rather than when-to-use. There is no statement of when to pick this over rego_test, rego_test_multiroot, or rego_eval_with_coverage, so selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_depsRego dependency analysisARead-onlyIdempotent
Static dependency analysis for a Rego reference. Given a target ref like "data.example.allow", returns the base document references (input/data leaves) and virtual document references (rules) it depends on, transitively.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | Reference to compute dependencies for, e.g. "data.example.allow". | |
| paths | Yes | Policy / data paths to load before computing dependencies. Each must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the description's mention of 'static analysis' adds context but does not disclose additional behavioral traits like performance or side effects beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the purpose and key details. No redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description explains what the tool returns (base and virtual document references, transitively). It covers purpose, parameters, and output sufficiently for a static analysis tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, baseline 3. The description adds meaning by explaining the ref format (e.g., 'data.example.allow') and the paths constraint (must be inside allowed root), which adds value beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool performs static dependency analysis for a Rego reference, specifying the target ref format and what it returns (base and virtual document references). This distinguishes it from sibling tools like rego_check or rego_eval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for dependency analysis but does not explicitly state when to use this tool versus alternatives like rego_eval or rego_explain_decision. No when-not or alternative guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_describe_policyDescribe Rego policyARead-onlyIdempotent
Parse a Rego policy and return a structured summary: package, imports, and rules. Each rule reports clauseCount (how many definitions share the name), isDefault (true if any clause is a default), hasArgs, bodyLength (total body expressions across all clauses), and inline annotations. Useful as the first step in any "what does this policy do" workflow.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Rego source to describe. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so safety is covered; the description adds valuable context by spelling out the exact report structure (clauseCount, isDefault, hasArgs, bodyLength, inline annotations). It does not mention error behavior for malformed source, a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three front-loaded sentences: purpose first, then return-field detail, then a usage cue. The field enumeration is dense but each clause earns its place by clarifying output for a tool without an output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully documents return shape and both parameters are covered by the schema, so an agent has enough to call it correctly. It lacks explicit sibling routing, which is the main missing piece.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; both `source` and the rich `v0Compatible` explanation are already fully documented in the schema, and the description adds no additional parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (describe/parse) and resource (Rego policy), then enumerates the returned summary fields (package, imports, rules, clauseCount, isDefault, hasArgs, bodyLength). It is unambiguous what it does, though it does not explicitly contrast itself with near-siblings like rego_parse_ast or rego_inspect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Useful as the first step in any 'what does this policy do' workflow" implies a usage context, but there are no explicit when-to-use/when-not conditions or named alternatives among the many sibling analysis tools (rego_inspect, rego_parse_ast, rego_check).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_evalEvaluate Rego queryA
Evaluate a Rego query against a policy and an input document using opa eval. Returns the standard {result: [...]} shape. The bread-and-butter authoring tool. The policy is optional, so a query alone tries out a built-in or an expression. Pass inputs to evaluate one query against many input documents in one call, and v0Compatible for a policy still written in pre-1.0 Rego.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Inline input document. | |
| paths | No | Policy / data file or directory paths. Each must be inside an allowed root. | |
| query | Yes | Rego query to evaluate, e.g. "data.example.allow". | |
| inputs | No | Several input documents to evaluate the same query against, up to 50, in place of `input`/`inputPath`. The result is `batch`: one entry per input, in order, each holding that input's `result` (empty when the query was undefined for it) or an `error`. An input that fails at runtime does not stop the others. A policy that does not compile fails the call, and after an input times out the inputs not yet started come back as `NOT_EVALUATED`. | |
| source | No | Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression. | |
| partial | No | Run partial evaluation rather than full evaluation. | |
| unknowns | No | Refs to treat as unknown during partial evaluation. | |
| inputPath | No | Path to a JSON input file. Mutually exclusive with `input`. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| strictBuiltinErrors | No | Treat builtin errors as fatal instead of returning undefined. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=true, so the safety profile is partially covered; the description adds real value beyond them by disclosing the return shape (`{result: [...]}`), the pre-1.0 Rego compatibility path, and the fact that a query can run with no policy at all. It does not restate or contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four compact sentences, front-loaded with what the tool does and the return shape before the optional-parameter notes. The colloquial "bread-and-butter authoring tool" is a slight indulgence but it conveys routing value cheaply.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description usefully supplies the return shape and the headline behaviors, so the essentials an agent needs to call it are present. What is missing is disambiguation from the large cluster of near-identical eval/query siblings, which the description never addresses.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 10 parameters thoroughly, including the batch semantics of `inputs` and the v0 rationale for `v0Compatible`. The description's parameter remarks (policy optional, `inputs` for many documents, `v0Compatible` for pre-1.0 policies) largely duplicate the schema text, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Evaluate a Rego query against a policy and an input document using `opa eval`") and calls itself the "bread-and-butter authoring tool," which positions it as the default entry point. It never names a specific sibling (rego_eval_with_explain, rego_eval_with_profile, rego_eval_with_coverage, opa_query_decision), so an agent must infer the distinction from the surrounding tool list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives implied usage context: policy is optional so a bare query works for built-ins/expressions, and `inputs` enables batching one query against many documents. There are no exclusions and no explicit routing to the decorated eval variants (explain/profile/coverage) that share almost the same job, which is the main decision an agent faces here.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_eval_with_coverageEvaluate Rego with coverageA
Evaluate with --coverage and return per-line coverage data. Useful for verifying that tests actually exercise the rules they're meant to.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Inline input document. | |
| paths | No | Policy / data file or directory paths. Each must be inside an allowed root. | |
| query | Yes | Rego query to evaluate, e.g. "data.example.allow". | |
| source | No | Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression. | |
| partial | No | Run partial evaluation rather than full evaluation. | |
| unknowns | No | Refs to treat as unknown during partial evaluation. | |
| inputPath | No | Path to a JSON input file. Mutually exclusive with `input`. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| strictBuiltinErrors | No | Treat builtin errors as fatal instead of returning undefined. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations give only readOnlyHint=false and openWorldHint=true, so the description carries most of the behavioral burden. It discloses the return content (per-line coverage data), which is genuinely useful without an output schema, but says nothing about cost, performance, or what happens under partial evaluation. Notably readOnlyHint=false for an eval tool is odd, though the description neither confirms nor contradicts it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the distinguishing behavior (coverage) front-loaded and the rationale following. Zero wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With nine parameters, sparse annotations, and no output schema, the description is thin for a tool whose headline output is coverage data. It states that per-line coverage is returned but does not characterize that shape or note anything about partial/unknowns interaction, leaving the schema and agent inference to fill sizable gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all nine parameters, including partial/unknowns and v0Compatible in notable detail. The description adds only the implicit `--coverage` flag mapping and no syntax or format guidance beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Evaluate with `--coverage` and return per-line coverage data.' This clearly separates it from the plain `rego_eval` and from the explain/profile variants. It never names a sibling explicitly, but the coverage framing is distinctive enough for an agent to select it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an implied when-to-use: 'verifying that tests actually exercise the rules they're meant to.' That is real context, but there is no when-not guidance and no routing to related siblings like rego_coverage_gaps, rego_test, or rego_eval_with_explain.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_eval_with_explainEvaluate Rego with execution traceA
Evaluate with --explain=full and return a structured trace alongside the result. Use this when an agent needs to see why a rule fired (or didn't) -- the trace is the basis for rego_explain_decision.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Inline input document. | |
| paths | No | Policy / data file or directory paths. Each must be inside an allowed root. | |
| query | Yes | Rego query to evaluate, e.g. "data.example.allow". | |
| source | No | Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression. | |
| partial | No | Run partial evaluation rather than full evaluation. | |
| unknowns | No | Refs to treat as unknown during partial evaluation. | |
| inputPath | No | Path to a JSON input file. Mutually exclusive with `input`. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| strictBuiltinErrors | No | Treat builtin errors as fatal instead of returning undefined. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover readOnlyHint=false and openWorldHint=true, so the description's disclosure that this runs with full explain mode and returns a trace alongside the result is meaningful added context. It doesn't describe trace verbosity/size or how the trace is structured, but the core behavioral trait is surfaced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences with the core action front-loaded and no filler. The chained-tool note is brief and earns its place as routing context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter evaluation tool with no output schema, the description conveys the essential behavior (trace returned with result) and the workflow purpose. It could say more about what the returned trace contains, since no output schema exists to compensate, but it is sufficient to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all nine parameters (including the `--explain`-relevant ones like `partial`, `unknowns`, `v0Compatible`) are already documented in the schema. The description adds no parameter-level meaning beyond what the schema provides, which is the expected baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (evaluate Rego with `--explain=full` returning a structured trace) and names the differentiator versus plain evaluation. It also positions the tool relative to a sibling (`rego_explain_decision`), so an agent can distinguish it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use this when an agent needs to see why a rule fired (or didn't)" is an explicit, actionable trigger condition, and it hints at the downstream relationship with `rego_explain_decision`. It stops short of stating when to prefer plain `rego_eval` over this costlier variant (e.g. when no explanation is needed), so no exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_eval_with_profileEvaluate Rego with profilingA
Evaluate with --profile and return per-rule timing and evaluation counts. Use this to find hot rules in slow policies.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Inline input document. | |
| paths | No | Policy / data file or directory paths. Each must be inside an allowed root. | |
| query | Yes | Rego query to evaluate, e.g. "data.example.allow". | |
| source | No | Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression. | |
| partial | No | Run partial evaluation rather than full evaluation. | |
| unknowns | No | Refs to treat as unknown during partial evaluation. | |
| inputPath | No | Path to a JSON input file. Mutually exclusive with `input`. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| strictBuiltinErrors | No | Treat builtin errors as fatal instead of returning undefined. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=true, and the description does not contradict them. It adds useful behavioral context by stating the output shape (per-rule timing and evaluation counts) rather than a plain decision result. It does not mention cost/overhead of profiling, path-root restrictions, or interplay with partial evaluation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler; the capability is front-loaded and the usage hint follows. Nothing could be removed without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with no output schema, the description discloses what profiling returns (timings plus counts) and when to reach for it, which covers the main gaps. It omits return-format specifics and any caveat about profiling cost, so it is good but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% across all 9 parameters, so the schema already carries parameter meaning. The description adds no parameter-level detail (e.g. that profiling is meaningless without paths/source). Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (evaluate) plus the distinguishing artifact: `--profile` mode returning per-rule timing and evaluation counts. This differentiates it from plain rego_eval and from the explain/coverage variants without naming them explicitly. It is clear but stops short of sibling-level routing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use this to find hot rules in slow policies" gives a genuine use case, so usage is more than merely implied. However, it names no alternative and gives no exclusions, which matters here because rego_eval, rego_eval_with_explain, rego_eval_with_coverage and rego_bench all overlap and an agent must choose among them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_explain_decisionExplain Rego decisionA
Evaluate a Rego query with full tracing and return a structured trace plus per-rule fired/not-fired summary. Use this when you need to answer "why was this denied?" -- the agent reads the structured trace and narrates the cause without re-implementing the trace parser.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Inline input document. | |
| paths | No | Policy / data file or directory paths. Each must be inside an allowed root. | |
| query | Yes | Rego query to evaluate, e.g. "data.example.allow". | |
| source | No | Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression. | |
| partial | No | Run partial evaluation rather than full evaluation. | |
| unknowns | No | Refs to treat as unknown during partial evaluation. | |
| inputPath | No | Path to a JSON input file. Mutually exclusive with `input`. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| strictBuiltinErrors | No | Treat builtin errors as fatal instead of returning undefined. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds genuine context beyond annotations by describing the return shape and the intended agent workflow (read trace, narrate cause, no custom parser). With annotations limited to readOnlyHint=false/openWorldHint=true, it still omits any disclosure of tracing cost, side effects, or why the call is flagged non-read-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two well-formed sentences, front-loaded with what the tool does followed by when to use it. No filler; only lightly redundant restatement of the output in the second clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter, no-output-schema tool, the description compensates by naming the return contents (structured trace, per-rule fired/not-fired summary) and the intended usage. Behavioral specifics like tracing performance and the non-read-only flag remain unaddressed, keeping it short of full completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 9 parameters (v0Compatible, partial, unknowns, etc.). The description adds no format/syntax detail beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (evaluate a Rego query with full tracing) and its distinctive output (structured trace + per-rule fired/not-fired summary), which separates it from plain rego_eval. It does not, however, name the close siblings (rego_eval_with_explain, rego_explain_undefined) that an agent must choose between.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear motivating scenario ('why was this denied?'), which implies when to reach for it. But it gives no explicit exclusions or alternatives, and with near-identical siblings like rego_eval_with_explain and rego_explain_undefined present, the agent is left to infer the routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_explain_undefinedExplain why a Rego query is undefinedA
Diagnose why a fully-qualified Rego query (e.g. "data.authz.allow") produces no value, or falls back to its default. Combines a plain eval, a full-trace eval, and per-condition AST analysis to identify the exact body expression blocking each rule. Handles both runtime failures (trace-based) and indexer elimination (standalone condition eval). A rule written with default allow := false always has a value, so queryResult reports default for it and the same per-rule breakdown follows: the question "why is allow false" is the question this answers. Returns a structured breakdown of which conditions blocked each rule plus a human-readable summary.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Input document (JSON value) for the query. | |
| paths | No | Policy .rego file paths to load. Mutually exclusive with source. | |
| query | Yes | Fully-qualified rule reference to explain, e.g. "data.authz.allow". Must match the path you would pass to rego_eval. | |
| source | No | Inline Rego source to analyse. Mutually exclusive with paths. | |
| inputPath | No | Path to an input JSON file. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations marking this readOnlyHint=false and openWorldHint=true, the bar is lower, and the description adds real context: it combines three analysis passes, covers both runtime failures (trace-based) and indexer elimination (standalone condition eval), and explains how `default` rules are reported via `queryResult`. It also states the return shape (structured breakdown plus a human-readable summary), which matters because there is no output schema. It does not explain why the tool is flagged non-read-only, a minor omission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and mechanism, and most sentences carry information. The middle sentence about `default allow := false` and `queryResult` is convoluted and ends on a tautology ('the question ... is the question this answers'), which is the one place that does not earn its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter diagnostic tool with no output schema, the description does the necessary work: it explains the two failure classes handled and summarizes the return payload. It stops short of describing behavior when the query is actually defined (does it error, return empty, or succeed silently), which an agent would want to know before calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the description largely restates it (fully-qualified query, defaults, v0 compatibility is covered in the schema). It adds only marginal param meaning, e.g. the requirement that the query path match what you would pass to rego_eval. Baseline 3 is correct when the schema carries the documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (diagnose/explain) and a precise resource/scope: a fully-qualified Rego query that produces no value or falls back to a default. It further distinguishes the scenario from a generic eval by describing the mechanism (plain eval + full-trace + per-condition AST analysis). It does not, however, name the nearby siblings it must be distinguished from (rego_eval_with_explain, rego_explain_decision), so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the tool is for the case where a query is undefined or returns a default. There is no explicit 'when not to use this' or a named alternative such as rego_eval or rego_explain_decision for the case where the query does produce a value. The awkward restatement that 'why is allow false' is the question this answers adds scenario color but not routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_fixAuto-fix Rego violationsADestructive
Run regal fix to automatically apply mechanical fixes. Regal 0.42 fixes opa-fmt, use-rego-v1, use-assignment-operator, no-whitespace-comment, directory-package-mismatch, non-raw-regex-pattern, prefer-equals-comparison, redundant-existence-check and constant-condition; older releases fix a subset. Use dryRun: true to preview changes before modifying files. NOTE: directory-package-mismatch moves files to match their package path -- use disable: ["directory-package-mismatch"] to skip it. Regal before 0.41 refuses files with uncommitted git changes unless force: true. Requires regal.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | On Regal before 0.41, allow fixing files that have uncommitted git changes; those releases refuse them otherwise. Regal 0.41 removed that check, and the flag is not sent to it. | |
| paths | Yes | Policy files or directories to fix. Each must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). | |
| dryRun | No | Preview what would be fixed without modifying any files. Recommended before the first real run. | |
| enable | No | Enable specific fix rules. | |
| disable | No | Disable specific fix rules. Useful to skip directory-package-mismatch if you do not want files moved. | |
| configFile | No | Path to a Regal config file (.regal/config.yaml). | |
| ignoreFiles | No | Glob patterns to exclude from fixing. | |
| enableCategory | No | Enable all rules in a category. | |
| disableCategory | No | Disable all rules in a category. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive behavior; the description adds crucial specifics: directory-package-mismatch moves files, Regal before 0.41 refuses uncommitted changes unless force:true, and regal must be installed. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but well-structured: main action first, then rule list, then critical safety caveats. Every sentence adds necessary information; the directory-package-mismatch warning is essential for a destructive tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool with 9 parameters and no output schema, the description covers the key behavioral caveats (file moves, git check, dryRun preview, regal requirement). It doesn't explain return values, but that's not critical for a fix command, and the schema handles parameter details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all 9 parameters at 100%, so baseline is 3. The description adds value by explaining the behavior behind dryRun, disable, and force in context (preview, skip file moves, version-specific git check), going beyond the schema's per-parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the exact command ('Run regal fix') and the resource ('Rego violations') with a specific list of mechanical fixes. The title and description together make it clear this applies fixes rather than just reporting them, distinguishing it from rego_lint and rego_format.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear operational guidance: dryRun for preview, disable for directory-package-mismatch, force for older Regal. It does not explicitly name sibling alternatives or state when not to use it, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_formatFormat RegoARead-onlyIdempotent
Format Rego source code using opa fmt. Returns the formatted source and a changed flag indicating whether the input was already canonical. When the source uses string interpolation ($"..." or $... syntax) and OPA v1.12.0 or v1.12.1 is detected, the tool warns about or blocks formatting due to a known OPA bug that corrupts { escape sequences (fixed in OPA v1.12.2).
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Rego source code to format. | |
| v0Compatible | No | Format a policy written in pre-1.0 Rego as pre-1.0 Rego (`--v0-compatible`), leaving its syntax as it is. OPA 1.x otherwise refuses it. To convert it to Rego v1 instead, use `rego_migrate_v1`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful behavioral context by explaining the `changed` flag and the OPA v1.12.0/v1.12.1 bug warning/blocking behavior. The phrase 'warns about or blocks' is slightly ambiguous, but it still discloses an important edge case beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. It front-loads the core purpose, then covers return behavior and the notable OPA bug edge case. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the return value (`formatted source` and `changed` flag) and the important version-specific bug behavior, which is sufficient for most calls. It is slightly incomplete because it does not clarify the distinction from `rego_format_write` and leaves the warn-vs-block behavior ambiguous, but overall it covers the key operational details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both `source` and `v0Compatible` clearly. The tool description adds no additional parameter-level meaning beyond what the schema provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool formats Rego source code using `opa fmt` and returns the formatted source plus a `changed` flag. This is a specific verb+resource and is easy to understand, but it does not explicitly distinguish itself from the sibling `rego_format_write` or other formatting-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for formatting Rego source, and the `v0Compatible` parameter description explicitly routes conversion to Rego v1 to `rego_migrate_v1`. However, there is no general guidance on when to choose this tool over `rego_format_write`, `rego_fix`, or other alternatives, so usage context is only partially addressed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_format_writeFormat Rego files in placeADestructiveIdempotent
Run opa fmt --write to canonically format one or more Rego files or directories in place. Use dryRun: true to preview which files would change without modifying them. Returns a list of files that were (or would be) reformatted. Unlike rego_format which returns formatted source as a string, this tool writes directly to disk. Supports regoV1, v0Compatible, and v1Compatible flags for version-specific formatting. If any file cannot be parsed, the operation is aborted and no files are written.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Policy files or directories to format in place. Each must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). | |
| dryRun | No | Preview which files would be reformatted without modifying them. Recommended before the first real run. | |
| regoV1 | No | Format module(s) to be compatible with both Rego v1 and the current OPA version. Adds `import rego.v1` where missing. | |
| v0Compatible | No | Use OPA behaviors and syntax prior to the v1.0 release. | |
| v1Compatible | No | Use OPA v1.0-compatible behaviors. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true. Description adds details: writes to disk, dryRun preview, abort on parse failure. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, front-loaded with main action, then key features (dryRun, return value, sibling differentiation, flags, error behavior). Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with 5 params and no output schema, description covers return format, error behavior, version flags, and safety. Could mention idempotency or permissions, but redundant with annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%. Description adds meaning: paths must be within allowed root, dryRun for preview, regoV1 adds import rego.v1, v0Compatible/v1Compatible for version-specific formatting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool runs `opa fmt --write` to format Rego files in place. Distinguishes from sibling `rego_format` by noting this writes to disk vs returning a string. Lists version flags.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly recommends using `dryRun: true` for preview and distinguishes from `rego_format`. Mentions abort on parse failure. Could explicitly state when not to use, but differentiation is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_generate_test_skeletonGenerate Rego test skeletonARead-onlyIdempotent
Generate a *_test.rego skeleton from a policy. Parses the AST, finds each non-test rule, and emits one stub test per rule. Existing test_* and todo_test_* rules are skipped automatically -- only production rules get stubs, and a value rule whose head is computed gets a todo_test_ stub, which opa test reports as skipped until its expected value is filled in and it is renamed test_. The AST is walked to infer which input.* fields the policy accesses; the inferred shape is used as the placeholder with input as {...} in each stub, so the developer only needs to fill in realistic values rather than guess the structure. With tableStyle: true, each stub uses an every tc in cases { ... } loop so you can add multiple input/expected pairs without duplicating assertion code. The inferredInputShape field in the response shows the detected shape for reference.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Rego source to generate tests for. | |
| tableStyle | No | Generate table-driven test stubs instead of single-case stubs. Each rule gets a `cases` array and an `every tc in cases { ... }` assertion loop. Pair with `rego_test varValues: true` to see which case failed. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`). The stubs are still written with `import rego.v1`, which a v0 test run (`rego_test` with `v0Compatible`) accepts too. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, yet the description goes well beyond them: it discloses stub-skipping semantics, the `todo_test_` -> `test_` rename workflow and how `opa test` reports it as skipped, AST-based `input.*` inference feeding the `with input as {...}` placeholder, and the response's `inferredInputShape` field. This is rich behavioral context an agent cannot get from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then layers on skip behavior, input-shape inference, tableStyle, and the response field. It is dense but every sentence carries distinct information; slightly long but no obvious filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description names the relevant return field (`inferredInputShape`) and explains the generated artifact's structure. For a read-only generator with three fully-described params, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds real meaning: `tableStyle` is explained as an `every tc in cases { ... }` loop with a cross-reference to `rego_test varValues: true`, and `v0Compatible` semantics (stubs still emit `import rego.v1`) are clarified. It adds value beyond the schema's parameter list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and artifact ('Generate a `*_test.rego` skeleton from a policy') and immediately scopes it against sibling tools by describing what is generated (stub tests per non-test rule) versus run. An agent can distinguish it from rego_test/rego_test_multiroot without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly describes the generation context (skips existing `test_*`/`todo_test_*` rules, emits `todo_test_` for computed-head value rules) and explains when to use `tableStyle` (multiple input/expected pairs). It does not explicitly name alternative sibling tools or state exclusions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_infer_input_schemaInfer input schemaARead-onlyIdempotent
Statically analyse one or more Rego policies and return a JSON Schema (draft-07) object describing every input.* field the policies read. Uses opa parse for AST-level analysis -- no running OPA server required. Correct starting point for writing integration tests, configuring opa check --schema validation, or documenting a policy API. Accepts inline source, individual files, or directories (walked recursively for *.rego files).
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Policy files or directories to analyse. Each must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Directories are walked recursively for *.rego files. | |
| source | No | Inline Rego source to analyse. Mutually exclusive with paths. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered. The description usefully adds behavioural context beyond that: analysis is AST-level via `opa parse` with no running OPA server required (a real differentiator from opa_exec-style tools), and input may be inline source, individual files, or recursively walked directories. It omits failure behaviour on malformed Rego and any path-root error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core verb-resource-output and then the usage guidance and input modes; nothing is padding. Slightly dense -- the usage sentence could be trimmed -- but every clause contributes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly carries the return-value burden by specifying a draft-07 JSON Schema describing every input.* field read. Combined with the input-mode coverage and the existing annotations, an agent has everything needed to invoke this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents `paths`, `source`, and the fairly intricate `v0Compatible` flag. The description restates the source/file/directory modes but adds no detail the schema lacks, and never mentions v0Compatible. Baseline 3 is appropriate when structured fields carry the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (statically analyse), resource (one or more Rego policies), and output (a draft-07 JSON Schema of every input.* field read). That output framing separates it from near-siblings like rego_check_schema (validates against a schema), rego_parse_ast (returns an AST), and rego_inspect, so an agent can route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names three concrete downstream uses -- writing integration tests, configuring `opa check --schema`, documenting a policy API -- which tells the agent when this is the right starting point. It stops short of explicit exclusions or naming the sibling to prefer when you already have a schema and only want validation (rego_check_schema), so it is clear context rather than full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_inspectInspect bundle or policyARead-onlyIdempotent
Inspect an OPA bundle, policy directory, or single Rego file with opa inspect. Returns manifest data, namespaces, rule annotations, and (if signed) signature metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Path to a bundle archive (`*.tar.gz`), directory, or single Rego file. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds value beyond that by disclosing the actual return content (manifest data, namespaces, rule annotations, signature metadata if signed), which no annotation or output schema provides. It does not mention errors on unreadable paths, but that gap is minor for an inspection tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with zero filler: the first names the action and accepted inputs, the second enumerates the outputs. Everything is front-loaded and each clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, annotation-covered read tool with no output schema, the description supplies the missing return-value information an agent would otherwise lack. The only shortfall is the absence of when-to-use guidance relative to the many sibling inspection/parsing tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: both `target` and `v0Compatible` are thoroughly documented in the schema, including the v0 syntax details. The description adds no parameter-level meaning beyond what the schema already carries, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (inspect) plus the exact resources it accepts (bundle archive, policy directory, single Rego file) and the underlying command (`opa inspect`). It also enumerates the returned artifacts (manifest, namespaces, rule annotations, signature metadata), which distinguishes it from siblings like rego_deps, rego_describe_policy, and opa_list_policies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description never says when to choose this over alternatives such as rego_deps, rego_describe_policy, or rego_parse_ast. It only states what the tool does, leaving the selection decision entirely to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_lintLint RegoA
Lint Rego source with the Regal linter. Returns categorized violations (style, bugs, idiomatic, performance) with file/line locations. Requires regal on PATH or REGAL_BINARY set; returns REGAL_NOT_FOUND otherwise. When called with inline source, location-bound rules whose verdict depends on the on-disk path (directory-package-mismatch) are auto-disabled to avoid temp-file false positives, and location.file is reported as <inline> instead of the randomized temp path. Re-enable those rules via enable if your workflow actually needs them.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | No | Filesystem paths to lint. Each path must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). | |
| enable | No | Enable specific named rules. | |
| source | No | Inline Rego source. Mutually exclusive with `paths`. | |
| disable | No | Disable specific named rules. | |
| failLevel | No | Severity at which Regal returns a non-zero exit. Default: `error`. | |
| configFile | No | Path to a Regal config file (defaults to .regal/config.yaml lookup). | |
| ignoreFiles | No | Glob patterns to skip. | |
| enableCategory | No | Enable entire rule categories. | |
| disableCategory | No | Disable entire rule categories (e.g. style, idiomatic, bugs). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond annotations. It discloses the external dependency (`regal` on PATH or `REGAL_BINARY`), the failure mode (`REGAL_NOT_FOUND`), the auto-disabling of path-dependent rules for inline source, and the `<inline>` path substitution. This is excellent behavioral disclosure that cannot be inferred from the schema. The `readOnlyHint: false` is consistent with a lint operation that launches an external process; no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and information-dense. The first sentence states the core purpose; the second covers dependencies and failure modes; the third explains conditional behavior for inline source. It is front-loaded and every sentence earns its place. A small deduction because the inline-source caveat is long and could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers return categories, dependency requirements, inline-source behavior, and path handling. With 9 parameters and no output schema, the remaining gap is the exact shape of the returned violation objects (e.g., severity codes, rule IDs). Still, for an agent choosing and invoking the tool, the most important operational details are present. Could mention that `paths` must be within allowed roots, but that is already in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter already has a description in the schema. The tool description does not repeat parameter details, which is appropriate. However, it also doesn't add semantic context about how `enable`/`disable`/`enableCategory`/`disableCategory` interact or how `failLevel` maps to exit codes beyond what the schema already says. Baseline 3 is fair because the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Lint'), a specific resource ('Rego source'), and names the actual linter ('Regal'). It also specifies returns 'categorized violations (style, bugs, idiomatic, performance) with file/line locations', which distinguishes it from other rego_* tools that analyze, transform, or evaluate Rego.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly explains how to invoke it with `paths` or inline `source`, and notes the behavior difference for the inline case. It doesn't explicitly spell out 'use X instead when...' alternatives, but the sibling list is large and the description's focus on inline-source behavioral detail implies the relevant context. Slight gap: no explicit statement about when to prefer rego_check, rego_fix, or rego_security_audit over this linter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_migrate_v1Migrate Rego to v1 syntaxA
Migrate Rego v0 source to Rego v1. First renames what v1 reserves (a rule called contains, every, if or in, and every reference to it in the module) and replaces built-ins v1 removed: re_match and net.cidr_overlap by their v1 names, and all, any, set_diff and the cast_* family by a helper function appended to the module that returns exactly what the built-in did, so behaviour does not change. re_match and net.cidr_overlap get such a helper too where the rename would change behaviour: the module mocks one spelling with with while calling both, or binds regex or net itself. Then opa fmt --rego-v1 converts the syntax (if, contains, import rego.v1) and opa check validates the result. rewrites lists each change by line and notes says why; a renamed rule must also be renamed in any other module that uses it. Pass inputs to evaluate the original as v0 and the result as v1 against each and compare every rule of the package, and queries to compare expressions too, such as calls to its functions; equivalence reports any difference. Evaluating runs the policy, http.send included. Returns the migrated source even when check finds remaining errors. A source that parses only as Rego v1 is returned unchanged; one that parses as both, such as v1 that imports rego.v1, is reformatted like any other. If the source parses as neither, returns INVALID_REGO with opa's own message.
| Name | Required | Description | Default |
|---|---|---|---|
| inputs | No | Up to 20 input documents to check the migration against. The original is evaluated as Rego v0 and the migrated policy as Rego v1 against each one, every rule of the package that is not a function is compared by value and by type, and `equivalence` reports any that differ. | |
| source | Yes | Rego v0 source to migrate to Rego v1 syntax. Rules named with a word v1 reserves are renamed and built-ins v1 removed are replaced before `opa fmt --rego-v1` converts the syntax; any remaining issues are returned in `errors` so you can resolve them manually. | |
| queries | No | Up to 10 Rego expressions to compare on each of `inputs` as well. A function has no value without arguments, so this is how functions are compared: `data.lib.names.label_ok(input.name, input.label)`. An expression that names a rule this tool renames, as `data.<package>.<rule>`, reaches it under its new name on the migrated side. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations only indicating readOnlyHint=false and openWorldHint=true, the description carries and exceeds the burden: it discloses the rename logic, built-in replacement via appended helpers, behaviour-preservation intent, that evaluation runs the policy 'http.send included' (matching openWorldHint), that migrated source is returned even when check finds errors, and the INVALID_REGO failure mode. No contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence and every subsequent sentence carries concrete information (rename rules, equivalence reporting, edge cases). It is dense and long, but the length is largely earned by genuine tool complexity; only minor tightening is possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must cover return values, and it does: `rewrites`, `notes`, `equivalence`, `errors`, and the `INVALID_REGO` message. Combined with the mutation/network annotations, an agent has everything needed to call and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: it explains that `inputs` drives per-rule value/type comparison with `equivalence` reporting differences, and that `queries` is how functions are compared and can resolve names this tool renames. This goes beyond the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Migrate Rego v0 source to Rego v1.' It clearly delineates this from siblings like rego_format and rego_check by explaining it performs renames/built-in replacement, then delegates syntax conversion and validation to those tools internally.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for when the tool applies (v0 sources needing v1 migration) and handles edge cases: source that parses only as v1 is returned unchanged, source parsing as neither returns INVALID_REGO. However, it never explicitly names sibling alternatives (e.g., rego_fix, rego_format) or states when NOT to reach for this tool, so routing among the many rego_* siblings is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_parse_astParse Rego to ASTARead-onlyIdempotent
Parse Rego source to a JSON AST using opa parse. Returns the AST as a tree of nodes (package, imports, rules, expressions, terms). Use this when you need to introspect policy structure programmatically.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Rego source code to parse. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, idempotentHint, destructiveHint=false, so the safety profile is covered. The description adds that output is a node tree, but says nothing about behavior on malformed Rego (parse error vs partial AST) or dependency on the local `opa` binary. Anti-nothing contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and mechanism, then the return shape, then usage. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully characterizes the return value as a node tree, and the complex v0Compatible semantics live in the schema. Missing only minor operational detail such as error behavior, which prevents a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both `source` and `v0Compatible` are already documented at length in the schema. The description adds no parameter-level meaning beyond that, which is the baseline-3 case.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (parse Rego source) and the concrete mechanism (`opa parse`), plus the output shape (JSON AST tree of package/imports/rules/expressions/terms). It does not explicitly name which sibling it replaces, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use this when you need to introspect policy structure programmatically" gives implied usage, but there is no when-not guidance and no contrast with plausible alternatives such as rego_inspect or rego_describe_policy, which an agent could easily confuse for this task.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_policy_diffDiff two Rego policiesA
Evaluate the same query against two policies (or two versions of the same policy) and compare the results. Both evaluations run in parallel. Returns equal: true/false, the raw result from each side, and changedPaths -- the dot/bracket paths that differ. Useful for verifying that a refactor preserves behavior, or understanding exactly where two policies diverge. Each side takes either inline source (sourceA/sourceB) or a file/directory path (pathA/pathB). The same input and query are used for both evaluations.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Inline input document (JSON). Mutually exclusive with inputPath. | |
| pathA | No | File or directory path for policy A. Must be inside an allowed root. Mutually exclusive with sourceA. | |
| pathB | No | File or directory path for policy B. Must be inside an allowed root. Mutually exclusive with sourceB. | |
| query | Yes | The query to evaluate against both policies, e.g. "data.example.allow". | |
| sourceA | No | Inline Rego source for policy A. Mutually exclusive with pathA. | |
| sourceB | No | Inline Rego source for policy B. Mutually exclusive with pathB. | |
| dataPaths | No | Additional data or policy paths loaded for both evaluations. Each must be inside an allowed root. | |
| inputPath | No | Path to a JSON input file. Must be inside an allowed root. Mutually exclusive with input. | |
| v0CompatibleA | No | Read policy A as Rego v0 (`--v0-compatible`), the syntax before OPA 1.0. Set this and leave `v0CompatibleB` off to compare a legacy policy with its migrated copy. | |
| v0CompatibleB | No | Read policy B as Rego v0 (`--v0-compatible`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real behavioral context beyond the annotations: both evaluations run in parallel, the same input/query are shared across both sides, and the return shape (equal, raw result per side, changedPaths) is spelled out. The annotations (readOnlyHint=false, openWorldHint=true) are covered without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, all earning their place, with the core purpose and the return contract front-loaded ahead of the parameter pairing details. Slightly denser than necessary but no wasted filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description still explains the return values (equal, per-side result, changedPaths) and the A/B source-or-path model, so an agent can call it correctly without inferring anything critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already 100%, so the baseline is 3, but the description adds the cross-parameter semantics the schema only states per-field: the A/B sides each accept either inline source or a path, and both sides share one input and query. That mutual-exclusivity and pairing logic is genuinely additive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Evaluate the same query against two policies and compare the results'), and is clearly distinguishable from siblings like rego_eval or rego_eval_with_explain which evaluate a single policy. An agent knows exactly what this does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete motivating use cases -- 'verifying that a refactor preserves behavior' and 'understanding exactly where two policies diverge' -- which tells the agent when this tool is the right choice. It stops short of naming an alternative tool or stating when NOT to use it, so it doesn't reach the top tier.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_security_auditRego security auditA
Run regal lint restricted to its bugs category, the correctness rules whose defects most often turn into policy bypasses, plus any custom rules placed in a security category, across one or more policy directories. Returns findings grouped by severity (high/medium) with remediation guidance. Use this for a periodic fleet-wide sweep rather than per-file style review. Requires regal.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Policy directories or files to audit. Each must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Pass the root of your policy fleet to scan everything at once. | |
| configFile | No | Path to a Regal config file. Useful when your repo has custom rule configuration. | |
| ignoreFiles | No | Glob patterns to exclude from the audit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, openWorldHint=true), the description discloses the return shape — findings grouped by severity (high/medium) with remediation guidance — and the prerequisite that regal must be installed. It also reveals the rule-selection behavior (correctness rules tied to policy bypasses plus custom security rules). Nothing stated contradicts the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences cover purpose, output format, usage context, and a prerequisite with no filler or repetition. The core action and scope are front-loaded in the first sentence, with the 'Requires regal' caveat appropriately tucked at the end.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the findings format (grouped by severity, with remediation guidance). The allowed-roots path constraint lives in the schema, and fleet-vs-per-file guidance covers usage context. Minor gaps like exit-code behavior are acceptable for a non-mutating lint tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with paths, configFile, and ignoreFiles each documented, including the allowed-roots constraint on paths and the fleet-roots hint. The description adds no parameter-specific meaning beyond what the schema already provides, so the high-coverage baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: it runs regal lint restricted to the `bugs` category plus custom `security`-category rules across policy directories. This precise rule-subset scope differentiates it from the general sibling rego_lint without needing to open that tool's schema. The action, resource, and scope are all explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Use this for a periodic fleet-wide sweep rather than per-file style review.' This clearly frames the intended context and rules out per-file review, but it stops short of naming a specific alternative tool for that excluded case, which keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_suggest_fixSuggest fix for Rego diagnosticsARead-onlyIdempotent
Map common Rego compile errors and Regal lint findings to mechanical fix suggestions. Pass diagnostics from rego_check or rego_lint. Returns one suggestion per input diagnostic; confidence is high for well-known patterns, medium for partial matches, low for everything else.
| Name | Required | Description | Default |
|---|---|---|---|
| diagnostics | Yes | Diagnostics from rego_check or rego_lint. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive. The description adds that it returns one suggestion per diagnostic and confidence levels (high/medium/low). This provides useful behavioral context beyond annotations, though it does not detail the output structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose, no unnecessary words. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and no output schema, the description explains input source, output quantity, and confidence levels. It does not describe the suggestion structure, but for a low-complexity tool, this is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for all fields. The description only adds that diagnostics should come from rego_check or rego_lint, which is helpful but minimal. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it maps compile errors and lint findings to fix suggestions, and specifies the source diagnostics. However, it does not explicitly differentiate from sibling tool rego_fix, which may apply fixes, leaving some ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to pass diagnostics from rego_check or rego_lint, providing clear usage context. Does not mention when not to use or alternatives, but the context is sufficient for an AI agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_testRun Rego testsA
Run Rego unit tests with opa test. Returns aggregate pass/fail/skip/error counts plus per-test records. errored counts tests OPA could not evaluate (a rule conflict, a raising built-in); such a test is neither a pass nor a failure, and a suite with any is not passing. Tests live in *_test.rego files; rule names beginning with test_ are picked up automatically. Use runPattern to filter by name regex; when no tests match, the error hint includes the pattern you supplied. Use threshold to gate on minimum coverage (returns COVERAGE_BELOW_THRESHOLD on failure). Use varValues: true with verbose: true to include local variable bindings in the trace -- essential for debugging table-driven tests written with every tc in cases { ... } to identify which case caused a failure. When tests use the test_x[case] parameterized form, OPA reports the rule as a single test whatever the number of cases; parameterizedGroups maps the rule name to a record per case and caseCounts totals them, so a failing rule says which case failed. Use ignorePatterns to exclude generated or fixture files. Use bundle: true when testing bundle-structured policy directories. Use timeout to raise the per-test limit beyond OPA's default 5s. Note: enabling coverage or threshold switches OPA to coverage-report output mode -- per-test counts are unavailable but coverage and coveragePct fields are populated.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of times to repeat the suite (`--count N`). Default is 1. Useful for catching flaky tests. OPA stops at the first repetition that fails, so `repetitions` in the output reports how many actually ran, and each test is listed once carrying its worst outcome across them. | |
| paths | Yes | Test directories or files. `opa test` looks for `*_test.rego` siblings of source files. | |
| bundle | No | Load paths as OPA bundle roots (`--bundle`). Required when testing policies structured as bundles with a `manifest.json` at the root. Not needed for plain policy directories. | |
| explain | No | Add a query-explanation trace to test records (`--explain`). `fails` traces only failing tests, `full` traces everything, `notes` surfaces `trace()` notes, `debug` is most verbose. Populates each record's `trace` field; pair with `verbose: true` for the human-readable trace output too. | |
| timeout | No | Per-test timeout as a Go duration string, e.g. `"30s"` or `"2m"` (`--timeout`). OPA's default is 5s. Increase for tests that load large policy sets or call slow built-ins. | |
| verbose | No | Emit per-test pass/fail details. | |
| coverage | No | Include per-line coverage data. Switches output to coverage-report mode: test record counts are not available, but `coverage` and `coveragePct` fields are populated. | |
| threshold | No | Minimum coverage percentage required (0–100). Returns COVERAGE_BELOW_THRESHOLD when actual coverage falls below this value. Implicitly enables coverage-report output mode. | |
| varValues | No | Include local variable bindings in trace output (`--var-values`). When a table-driven test using `every tc in cases { ... }` fails, the trace shows which `tc` triggered the failure. Has no effect unless `verbose: true` is also set (OPA only emits trace entries in verbose mode). | |
| runPattern | No | Run only tests whose names match this regular expression (passed as `--run`). | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| v1Compatible | No | Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`). | |
| ignorePatterns | No | Glob patterns for files to exclude from the test run (`--ignore <pattern>`). Pass one pattern per array element. Useful for excluding generated or fixture files that contain no tests (e.g. `["*_generated.rego", "fixtures/**"]`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnlyHint=false and openWorldHint=true, so the description carries most of the burden and does so well: it explains `errored` semantics (neither pass nor fail, suite not passing), the coverage/threshold output-mode switch and COVERAGE_BELOW_THRESHOLD error, the error-hint behavior echoing runPattern, and that varValues is inert without verbose. It stops short of warning that test execution runs arbitrary policy code with side-effect-capable built-ins.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and return shape, then a dense run of per-flag guidance; the length is justified by 13 parameters and no output schema. It is one unbroken block with no grouping, and a few points (verbose/varValues trace behavior) are restated verbatim from the schema, costing some efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and minimal annotations, the description does the necessary work of describing return fields (aggregate counts, per-test records, parameterizedGroups, caseCounts, coveragePct) and failure modes. It is nearly complete for a tool of this complexity; only the absence of sibling routing and execution-safety notes leaves a small gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with unusually rich per-parameter descriptions, so the baseline is 3. The description goes slightly beyond by consolidating cross-parameter interactions (varValues requires verbose; coverage/threshold switch output mode; count's worst-outcome aggregation) and by tying runPattern to the error hint, though much of this restates what the schema already says.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Run Rego unit tests with `opa test`") and immediately defines the scope of output (aggregate counts plus per-test records). It further distinguishes itself from generic evaluation siblings by describing test-discovery semantics (`*_test.rego`, `test_` prefix) that an agent can use to tell it apart from rego_eval or conftest_test.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance for individual options: runPattern for filtering, threshold for coverage gating, varValues+verbose for table-driven debugging, ignorePatterns for generated files, bundle for bundle-structured dirs, timeout for slow suites. It does not, however, name an alternative tool (e.g. rego_test_multiroot for multi-root runs, or conftest_test for the conftest flow) to route between siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_test_multirootRun Rego tests across multiple rootsA
Run opa test once per root and aggregate results. Solves the package-conflict problem that occurs when opa test . is run on a repo with multiple independent package namespaces (OPA issue #4724). Two modes: explicit (supply root list with optional per-root include paths for shared libraries) and scan (auto-discover leaf test roots using the leaf rule -- a directory is a root only if it directly contains *_test.rego files and none of its eligible subdirectories do, preventing OPA's automatic recursion from double-running tests). Use sharedPaths in scan mode to add shared library directories to every root's invocation without including them in discovery. Coverage and threshold work per-root; overallCoveragePct is the mean across roots that have coverage data.
| Name | Required | Description | Default |
|---|---|---|---|
| roots | No | Explicit list of test root directories. Use when roots are known upfront or when scan mode cannot determine the correct roots. Mutually exclusive with `scanDir`. | |
| scanDir | No | Top-level directory to scan for test roots. Uses the leaf rule: a directory is a root only if it directly contains `*_test.rego` files and none of its eligible subdirectories do. Mutually exclusive with `roots`. | |
| verbose | No | Emit per-test pass/fail details for each root. | |
| coverage | No | Include per-line coverage data per root. Switches output to coverage-report mode: test record counts are not available, but `coverage`, `coveragePct`, and `overallCoveragePct` fields are populated. | |
| maxDepth | No | Maximum directory depth to scan. Default: 10. Only used with `scanDir`. | |
| maxRoots | No | Maximum number of test roots allowed. Returns INVALID_INPUT if scan finds more. Default: 50. Only used with `scanDir`. | |
| threshold | No | Minimum coverage percentage required per root (0-100). Roots below threshold have `thresholdMet: false` in their result. Implicitly enables coverage-report output mode. | |
| varValues | No | Include local variable bindings in trace output (`--var-values`). Only useful with `verbose: true`. | |
| runPattern | No | Run only tests whose names match this regular expression (passed as `--run` to each root). | |
| sharedPaths | No | Paths added to every root's `opa test` invocation and excluded from auto-discovery. Use for shared library directories that all roots import from. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. | |
| ignorePatterns | No | Additional directory name patterns to skip during scan (e.g., ["vendor", "*.generated"]). Supports `*` wildcards. Only used with `scanDir`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, openWorldHint=true), the description discloses substantial behavior: the leaf rule and why it prevents OPA's recursion from double-running tests, that coverage/threshold apply per-root while overallCoveragePct is a mean over roots with coverage data, and that coverage switches the output mode. These are non-obvious execution semantics an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and the conflict it solves are front-loaded, and each subsequent sentence adds distinct information (modes, leaf rule, sharedPaths, coverage aggregation). It is dense and slightly long, with minor overlap between the description and schema descriptions, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so: it names the per-root result fields (thresholdMet), overallCoveragePct, and how coverage mode changes available output. For a 12-parameter, zero-required tool with nested root objects, it is complete enough to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each field (baseline 3). The description still adds cross-parameter meaning the schema cannot: mutual exclusivity of `roots`/`scanDir`, mode-specific relevance of `sharedPaths` and scan-only params, and the fact that `threshold` implicitly enables coverage-report mode.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource (run `opa test` per root and aggregate) and immediately differentiates from the plain `rego_test` sibling by naming the exact problem it solves (package-conflict on multi-namespace repos, OPA issue #4724). An agent can tell exactly what this does and why it exists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains the two operational modes (explicit vs scan) and when to use `sharedPaths` in scan mode, giving strong context. However, it never explicitly contrasts with the sibling `rego_test` tool ('use this instead when...'), leaving that selection to inference from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rego_verifyFormally verify a Rego policy ruleARead-onlyIdempotent
Formally verify a property about a Rego rule using SMT solving (Microsoft Z3). Unlike testing, this checks ALL possible inputs and either proves the property holds or returns a concrete counterexample input that falsifies it. Supports equality, comparison, startswith, endswith, contains, and simple regex.match patterns (prefix: ^lit.*, suffix: .lit$, exact: ^lit$, contains: .lit., wildcard: .). Complex regex patterns (character classes, quantifiers, alternation) return INCONCLUSIVE. Also reports INCONCLUSIVE for negation-as-failure (not), comprehensions, partial set and object rules (deny contains msg), functions, else chains, and any operand it cannot encode. A body that reads an absent field is undefined rather than true, so always_true holds only if the rule is also true for an empty input: a rule requiring input.x will be answered with the counterexample {}.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Property to prove: always_true - rule is true for every possible input (finds inputs that violate this) never_true - rule is never true for any input (finds inputs that trigger it) satisfiable - at least one input exists where rule is true (returns a witness) | |
| rule | Yes | Name of the rule to verify (e.g. "allow", "deny"). | |
| source | Yes | Rego source to verify. | |
| v0Compatible | No | Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the read-only/idempotent annotations by disclosing supported patterns, INCONCLUSIVE conditions (negation-as-failure, comprehensions, partial rules, functions, else chains, unencodable operands), and the subtle undefined-vs-true empty-input semantics with a concrete counterexample. This is exactly the behavioral context an agent needs to interpret results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core capability, then dense but purposeful detail; every sentence adds verification-relevant information rather than restating the name. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of return semantics and does so completely: prove-vs-counterexample behavior, INCONCLUSIVE cases, and the empty-input edge case are all covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so kind, rule, source, and v0Compatible are already fully documented in the schema, making the baseline 3 appropriate. The description adds interpretive context (e.g. undefined fields and the {} counterexample) but no syntax or format detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Formally verify a property about a Rego rule using SMT solving') and immediately anchors the mechanism (Microsoft Z3). It explicitly distinguishes itself from testing and other evaluation siblings by noting it checks ALL possible inputs and returns a counterexample.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context via contrast ('Unlike testing, this checks ALL possible inputs'), which selects it over rego_test/rego_eval, and enumerates when it returns INCONCLUSIVE. It does not name a specific alternative sibling tool, so routing is by implication rather than explicit reference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
26 tool updates
v0.8.0- Changed
conftest_push1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it.", + "type": "boolean" +}
- Changed
conftest_test1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policies as Rego v0 (`--rego-version v0`), the syntax before OPA 1.0: rules without `if`, `deny[msg] { ... }`. conftest reads v1 by default and refuses such a policy.", + "type": "boolean" +}
- Changed
conftest_verify1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policies as Rego v0 (`--rego-version v0`), the syntax before OPA 1.0: rules without `if`, `deny[msg] { ... }`. conftest reads v1 by default and refuses such a policy.", + "type": "boolean" +}
- Changed
opa_bundle_build1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
opa_exec2 fields changed- changed
Input schema / properties / dataPaths / descriptionPrevious value: -"Policy and data files or directories, loaded the way `opa eval --data` loads them: a `.rego` file as a module, a JSON or YAML file merged into the data root, a directory recursively, so every JSON and YAML file in it is data. A bundle among them (an archive, or a directory holding a `.manifest`) is loaded as a bundle instead; bundles and plain paths cannot be mixed. To load a directory as a bundle, reading only its data.json, pass it as `bundle`. Mutually exclusive with `bundle`."New value: +"Policy and data files or directories, loaded the way `opa eval --data` loads them: a `.rego` file as a module, a JSON or YAML file merged into the data root, a directory recursively, so every JSON and YAML file in it is data and must parse. One difference: a bundle archive (`.tar.gz`) inside a directory is not loaded, and `warnings` names it. A bundle given here directly (an archive, or a directory holding a `.manifest`) is loaded as a bundle; bundles and plain paths cannot be mixed. To load a directory as a bundle, reading only its `.rego` files and those named data.json, data.yaml or data.yml, pass it as `bundle`. Mutually exclusive with `bundle`." - changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_bench1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_check1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_check_schema1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_compile_query1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_coverage_gaps1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_describe_policy1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it.", + "type": "boolean" +}
- Changed
rego_eval1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_eval_with_coverage1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_eval_with_explain1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_eval_with_profile1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_explain_decision1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_explain_undefined1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it.", + "type": "boolean" +}
- Changed
rego_generate_test_skeleton1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`). The stubs are still written with `import rego.v1`, which a v0 test run (`rego_test` with `v0Compatible`) accepts too.", + "type": "boolean" +}
- Changed
rego_infer_input_schema1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it.", + "type": "boolean" +}
- Changed
rego_inspect1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_migrate_v12 fields changed- changed
Input schema / properties / inputs / descriptionPrevious value: -"Up to 20 input documents to check the migration against. The original is evaluated as Rego v0 and the migrated policy as Rego v1 against each one, every rule of the package is compared by value and by type, and `equivalence` reports any that differ."New value: +"Up to 20 input documents to check the migration against. The original is evaluated as Rego v0 and the migrated policy as Rego v1 against each one, every rule of the package that is not a function is compared by value and by type, and `equivalence` reports any that differ." - added
Input schema / properties / queriesAdded value: +{ + "description": "Up to 10 Rego expressions to compare on each of `inputs` as well. A function has no value without arguments, so this is how functions are compared: `data.lib.names.label_ok(input.name, input.label)`. An expression that names a rule this tool renames, as `data.<package>.<rule>`, reaches it under its new name on the migrated side.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" +}
- Changed
rego_parse_ast1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_policy_diff2 fields changed- added
Input schema / properties / v0CompatibleAAdded value: +{ + "description": "Read policy A as Rego v0 (`--v0-compatible`), the syntax before OPA 1.0. Set this and leave `v0CompatibleB` off to compare a legacy policy with its migrated copy.", + "type": "boolean" +} - added
Input schema / properties / v0CompatibleBAdded value: +{ + "description": "Read policy B as Rego v0 (`--v0-compatible`).", + "type": "boolean" +}
- Changed
rego_test1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_test_multiroot1 field changed- changed
Input schema / properties / v0Compatible / descriptionPrevious value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
- Changed
rego_verify1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it.", + "type": "boolean" +}
21 tool updates
v0.7.0- Changed
conftest_test4 fields changed- changed
Input schema / properties / inlineConfigParser / descriptionPrevious value: -"Parser to use for `inlineConfig`. One of: cue, dockerfile, dotenv, edn, hcl1, hcl2, hocon, ignore, ini, json, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. Defaults to yaml. Ignored when `files` is used (conftest infers the parser from each file's extension, unless `parser` is set)."New value: +"Parser to use for `inlineConfig`. One of: cue, cyclonedx, dockerfile, dotenv, edn, groovy, hcl1, hcl2, hocon, ignore, ini, json, jsonc, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. Defaults to yaml. Ignored when `files` is used (conftest infers the parser from each file's extension, unless `parser` is set)." - changed
Input schema / properties / inlineConfigParser / enumPrevious value: -[ - "cue", - "dockerfile", - "dotenv", - "edn", - "hcl1", - "hcl2", - "hocon", - "ignore", - "ini", - "json", - "jsonnet", - "nginx", - "properties", - "spdx", - "textproto", - "toml", - "vcl", - "xml", - "yaml" -]New value: +[ + "cue", + "cyclonedx", + "dockerfile", + "dotenv", + "edn", + "groovy", + "hcl1", + "hcl2", + "hocon", + "ignore", + "ini", + "json", + "jsonc", + "jsonnet", + "nginx", + "properties", + "spdx", + "textproto", + "toml", + "vcl", + "xml", + "yaml" +] - changed
Input schema / properties / parser / descriptionPrevious value: -"Force a specific parser for all input `files` via conftest's global `--parser` flag, overriding extension-based detection. Useful for files whose extension does not match their format (e.g. parse a `.tfstate` file as `json`). One of: cue, dockerfile, dotenv, edn, hcl1, hcl2, hocon, ignore, ini, json, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. For `inlineConfig`, prefer `inlineConfigParser`."New value: +"Force a specific parser for all input `files` via conftest's global `--parser` flag, overriding extension-based detection. Useful for files whose extension does not match their format (e.g. parse a `.tfstate` file as `json`). One of: cue, cyclonedx, dockerfile, dotenv, edn, groovy, hcl1, hcl2, hocon, ignore, ini, json, jsonc, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. For `inlineConfig`, prefer `inlineConfigParser`." - changed
Input schema / properties / parser / enumPrevious value: -[ - "cue", - "dockerfile", - "dotenv", - "edn", - "hcl1", - "hcl2", - "hocon", - "ignore", - "ini", - "json", - "jsonnet", - "nginx", - "properties", - "spdx", - "textproto", - "toml", - "vcl", - "xml", - "yaml" -]New value: +[ + "cue", + "cyclonedx", + "dockerfile", + "dotenv", + "edn", + "groovy", + "hcl1", + "hcl2", + "hocon", + "ignore", + "ini", + "json", + "jsonc", + "jsonnet", + "nginx", + "properties", + "spdx", + "textproto", + "toml", + "vcl", + "xml", + "yaml" +]
- Changed
opa_bundle_build1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
opa_exec2 fields changed- changed
Input schema / properties / dataPaths / descriptionPrevious value: -"Policy and/or data file or directory paths, each loaded as an OPA bundle root (opa exec loads policy only via bundles). Mutually exclusive with `bundle`."New value: +"Policy and data files or directories, loaded the way `opa eval --data` loads them: a `.rego` file as a module, a JSON or YAML file merged into the data root, a directory recursively, so every JSON and YAML file in it is data. A bundle among them (an archive, or a directory holding a `.manifest`) is loaded as a bundle instead; bundles and plain paths cannot be mixed. To load a directory as a bundle, reading only its data.json, pass it as `bundle`. Mutually exclusive with `bundle`." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_bench1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_capabilities1 field changed- changed
Input schema / properties / version / descriptionPrevious value: -"A specific OPA capabilities version (e.g. \"v1.19.0\"). When neither flag is set, lists available versions."New value: +"A specific OPA capabilities version (e.g. \"v1.21.0\"). When neither flag is set, lists available versions."
- Changed
rego_check1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_check_schema1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_compile_query2 fields changed- changed
Input schema / properties / source / descriptionPrevious value: -"Inline Rego policy source. Mutually exclusive with `paths`."New value: +"Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_coverage_gaps1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_eval3 fields changed- added
Input schema / properties / inputsAdded value: +{ + "description": "Several input documents to evaluate the same query against, up to 50, in place of `input`/`inputPath`. The result is `batch`: one entry per input, in order, each holding that input's `result` (empty when the query was undefined for it) or an `error`. An input that fails at runtime does not stop the others. A policy that does not compile fails the call, and after an input times out the inputs not yet started come back as `NOT_EVALUATED`.", + "items": {}, + "maxItems": 50, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / source / descriptionPrevious value: -"Inline Rego policy source. Mutually exclusive with `paths`."New value: +"Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_eval_with_coverage2 fields changed- changed
Input schema / properties / source / descriptionPrevious value: -"Inline Rego policy source. Mutually exclusive with `paths`."New value: +"Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_eval_with_explain2 fields changed- changed
Input schema / properties / source / descriptionPrevious value: -"Inline Rego policy source. Mutually exclusive with `paths`."New value: +"Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_eval_with_profile2 fields changed- changed
Input schema / properties / source / descriptionPrevious value: -"Inline Rego policy source. Mutually exclusive with `paths`."New value: +"Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_explain_decision2 fields changed- changed
Input schema / properties / source / descriptionPrevious value: -"Inline Rego policy source. Mutually exclusive with `paths`."New value: +"Inline Rego policy source. Optional: without `source` or `paths` the query runs on its own, which is enough to try a built-in or an expression." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_fix1 field changed- changed
Input schema / properties / force / descriptionPrevious value: -"Allow fixing files that have uncommitted git changes, or when the project is not a git repository. Without this flag regal refuses to touch uncommitted files."New value: +"On Regal before 0.41, allow fixing files that have uncommitted git changes; those releases refuse them otherwise. Regal 0.41 removed that check, and the flag is not sent to it."
- Changed
rego_format1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Format a policy written in pre-1.0 Rego as pre-1.0 Rego (`--v0-compatible`), leaving its syntax as it is. OPA 1.x otherwise refuses it. To convert it to Rego v1 instead, use `rego_migrate_v1`.", + "type": "boolean" +}
- Changed
rego_inspect1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_migrate_v12 fields changed- added
Input schema / properties / inputsAdded value: +{ + "description": "Up to 20 input documents to check the migration against. The original is evaluated as Rego v0 and the migrated policy as Rego v1 against each one, every rule of the package is compared by value and by type, and `equivalence` reports any that differ.", + "items": {}, + "maxItems": 20, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / source / descriptionPrevious value: -"Rego v0 source to migrate to Rego v1 syntax. `opa fmt --rego-v1` auto-fixes reserved keywords and adds `import rego.v1`; any remaining issues are returned in `errors` so you can resolve them manually."New value: +"Rego v0 source to migrate to Rego v1 syntax. Rules named with a word v1 reserves are renamed and built-ins v1 removed are replaced before `opa fmt --rego-v1` converts the syntax; any remaining issues are returned in `errors` so you can resolve them manually."
- Changed
rego_parse_ast1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_test1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
- Changed
rego_test_multiroot1 field changed- added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.", + "type": "boolean" +}
6 tool updates
v0.6.0- Changed
conftest_verify1 field changed- changed
Input schema / properties / namespace / descriptionPrevious value: -"Namespace to verify. Defaults to `main`. Omit to verify all namespaces."New value: +"Namespace to verify. Omit to verify all namespaces."
- Changed
opa_bundle_sign2 fields changed- changed
Input schema / properties / bundle / descriptionPrevious value: -"Path to a bundle directory or `.tar.gz` archive. Must be inside an allowed root."New value: +"Path to a bundle directory. Must be inside an allowed root. An archive is refused, since OPA reads the signature from inside it; build a signed archive with `opa_bundle_build` and `signingKey`." - removed
Input schema / properties / outputDirRemoved value: -{ - "description": "For an archive, the directory that receives `.signatures.json`; defaults to the archive's own directory. Must exist and be inside an allowed root. Not accepted for a directory bundle, which is signed in place.", - "type": "string" -}
- Changed
rego_bench1 field changed- changed
Input schema / properties / count / descriptionPrevious value: -"Number of times to repeat the benchmark (`--count N`). Defaults to OPA's built-in default of one. Every repetition is returned in `runs`; the top-level figures come from the fastest of them."New value: +"Number of times to repeat the benchmark (`--count N`). Defaults to OPA's built-in default of one. Above one, every repetition is returned in `runs`, `fastest` indexes the one the top-level figures come from, and `raw` is omitted since that document is in `runs`."
- Changed
rego_capabilities3 fields changed- added
Input schema / properties / builtinsAdded value: +{ + "description": "Return the full record (type signature, documentation, metadata) for up to 100 builtin names, exact matches only. `matched` counts the records returned and names not found are listed under `missing`. When the records would not fit the response cap the tool returns OUTPUT_TOO_LARGE rather than a truncated result; ask for fewer names. Do not combine with `names_only: true`, which asks for the opposite.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 100, + "minItems": 1, + "type": "array" +} - removed
Input schema / properties / names_only / defaultRemoved value: -true - changed
Input schema / properties / names_only / descriptionPrevious value: -"When true (default), return only builtin names, count, future keywords, and features. The full spec payload routinely exceeds client response size limits. Set to false to retrieve complete type signatures, documentation, and metadata for every builtin."New value: +"When true, or omitted, return only builtin names, count, future keywords, and features. The full payload for every builtin is larger than the default response cap (OPA_MCP_MAX_RESPONSE_BYTES), so `names_only: false` on its own needs that cap raised; use `builtins` to get full records for a few names instead."
- Changed
rego_check_schema1 field changed- changed
Input schema / properties / schemaPath / descriptionPrevious value: -"Path to a JSON Schema file on disk to use for `input` validation. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `inlineSchema`."New value: +"Path to a JSON Schema file on disk to use for `input` validation, or to a schema directory when the policy carries `# METADATA` / `schemas:` annotations naming files in it (opa reads a directory only through those). Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `inlineSchema`."
- Changed
rego_playground_share1 field changed- added
Input schema / properties / publicAdded value: +{ + "description": "Make the Gist public: listed on the account and searchable. Off by default, which creates a secret Gist that anyone holding the link can read but that is not listed anywhere.", + "type": "boolean" +}
16 tool updates
v0.5.0- Changed
conftest_pull1 field changed- changed
Input schema / properties / policy / descriptionPrevious value: -"Local directory where the pulled policies will be written. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Defaults to `./policy` (conftest's convention)."New value: +"Local directory where the pulled policies will be written. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Omitted, it falls back to `policy` in the working directory of the server process, the conftest convention, which must itself sit inside an allowed root. The directory is emptied before the pull, so do not point it at one holding anything you want to keep."
- Changed
conftest_push1 field changed- changed
Input schema / properties / policy / descriptionPrevious value: -"Path to the local directory containing Rego policies to push. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS) and must exist. Defaults to `./policy` (conftest's convention)."New value: +"Path to the local directory containing Rego policies to push. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS) and must exist. Omitted, it falls back to `policy` in the working directory of the server process, the conftest convention, which must itself sit inside an allowed root."
- Changed
conftest_test4 fields changed- changed
Input schema / properties / inlineConfigParser / descriptionPrevious value: -"Parser to use for `inlineConfig`. Valid values: yaml (default), json, toml, hcl1, hcl2, ini, xml, dotenv, cue, jsonnet, properties, edn, hocon, dockerfile. Ignored when `files` is used (conftest infers the parser from each file's extension, unless `parser` is set)."New value: +"Parser to use for `inlineConfig`. One of: cue, dockerfile, dotenv, edn, hcl1, hcl2, hocon, ignore, ini, json, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. Defaults to yaml. Ignored when `files` is used (conftest infers the parser from each file's extension, unless `parser` is set)." - added
Input schema / properties / inlineConfigParser / enumAdded value: +[ + "cue", + "dockerfile", + "dotenv", + "edn", + "hcl1", + "hcl2", + "hocon", + "ignore", + "ini", + "json", + "jsonnet", + "nginx", + "properties", + "spdx", + "textproto", + "toml", + "vcl", + "xml", + "yaml" +] - changed
Input schema / properties / parser / descriptionPrevious value: -"Force a specific parser for all input `files` via conftest's global `--parser` flag, overriding extension-based detection. Useful for files whose extension does not match their format (e.g. parse a `.tfstate` file as `json`). Valid values: yaml, json, toml, hcl1, hcl2, ini, xml, dotenv, cue, jsonnet, properties, edn, hocon, dockerfile. For `inlineConfig`, prefer `inlineConfigParser`."New value: +"Force a specific parser for all input `files` via conftest's global `--parser` flag, overriding extension-based detection. Useful for files whose extension does not match their format (e.g. parse a `.tfstate` file as `json`). One of: cue, dockerfile, dotenv, edn, hcl1, hcl2, hocon, ignore, ini, json, jsonnet, nginx, properties, spdx, textproto, toml, vcl, xml, yaml. For `inlineConfig`, prefer `inlineConfigParser`." - added
Input schema / properties / parser / enumAdded value: +[ + "cue", + "dockerfile", + "dotenv", + "edn", + "hcl1", + "hcl2", + "hocon", + "ignore", + "ini", + "json", + "jsonnet", + "nginx", + "properties", + "spdx", + "textproto", + "toml", + "vcl", + "xml", + "yaml" +]
- Changed
opa_bundle_build3 fields changed- changed
Input schema / properties / bundle / descriptionPrevious value: -"Load `paths` as bundle files or root directories (`--bundle`). Required when rebuilding or re-signing an existing bundle."New value: +"Load `paths` as bundle files or root directories (`--bundle`). Implied by `signingKey` and `verificationKey`; set it explicitly to rebuild an existing bundle without signing." - changed
Input schema / properties / signingKey / descriptionPrevious value: -"Path to a signing key for inline signing."New value: +"Path to a PEM private key for signing the built bundle (`--signing-key`). Implies `bundle: true`, which OPA requires for signing." - changed
Input schema / properties / verificationKey / descriptionPrevious value: -"Path to a PEM public key (or HMAC secret file) used to re-verify an existing signed bundle during the build (`--verification-key`). Pair with `bundle: true`."New value: +"Path to a PEM public key (or HMAC secret file) used to re-verify an existing signed bundle during the build (`--verification-key`). Implies `bundle: true`, which OPA requires for verification."
- Changed
opa_bundle_sign5 fields changed- changed
Input schema / properties / bundle / descriptionPrevious value: -"Path to a bundle directory or archive. Must be in an allowed root."New value: +"Path to a bundle directory or `.tar.gz` archive. Must be inside an allowed root." - changed
Input schema / properties / claimsFile / descriptionPrevious value: -"Path to extra claims to include in the signature."New value: +"Path to a JSON file of extra claims to sign, such as {\"keyid\": \"...\", \"scope\": \"...\"}. Must be inside an allowed root." - added
Input schema / properties / outputDirAdded value: +{ + "description": "For an archive, the directory that receives `.signatures.json`; defaults to the archive's own directory. Must exist and be inside an allowed root. Not accepted for a directory bundle, which is signed in place.", + "type": "string" +} - changed
Input schema / properties / signingAlg / descriptionPrevious value: -"Signing algorithm (e.g. RS256). Default: RS256."New value: +"Signing algorithm: RS256 (default), RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, HS256, HS384, HS512." - changed
Input schema / properties / signingKey / descriptionPrevious value: -"Path to the signing key."New value: +"Path to the PEM private key (RSA or ECDSA), or for HMAC algorithms a file holding the secret. Must be inside an allowed root."
- Changed
opa_bundle_verify4 fields changed- changed
Input schema / properties / scope / descriptionPrevious value: -"Expected `scope` value in the bundle signature. Required when the bundle was signed with `--scope`."New value: +"Expected `scope` claim in the signature. Pass exactly the value the bundle was signed with, and nothing if it was signed without one; the failure reason is scope_mismatch otherwise." - added
Input schema / properties / v0CompatibleAdded value: +{ + "description": "Load the bundle as Rego v0 (`--v0-compatible`). A policy written before Rego v1 otherwise fails to load, after the signature and digests have already been checked.", + "type": "boolean" +} - changed
Input schema / properties / verificationKey / descriptionPrevious value: -"Path to the PEM file containing the RSA or ECDSA public key, or the path to the HMAC secret file. Must be inside an allowed root."New value: +"Path to the PEM file containing the RSA or ECDSA public key, or for HMAC algorithms a file holding the secret. Must be inside an allowed root." - changed
Input schema / properties / verificationKeyId / descriptionPrevious value: -"Key ID that must match the `keyid` field in the bundle signature. Required when the bundle was signed with `--public-key-id`."New value: +"Name the key is registered under for OPA (`--verification-key-id`, default `default`). With a single key OPA verifies against it regardless of the signature keyid claim, so this rarely needs setting."
- Changed
opa_delete_data2 fields changed- added
Input schema / properties / segmentsAdded value: +{ + "description": "Path as literal key segments, e.g. [\"labels\", \"app.kubernetes.io/name\"]. Use instead of `path` when a key contains a dot or a slash.", + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "path" -]
- Changed
opa_exec1 field changed- changed
Input schema / properties / decision / descriptionPrevious value: -"The policy entrypoint to evaluate for each input, e.g. `\"data.authz.allow\"` or `\"data.policy.violations\"`. Must be a fully-qualified Rego reference."New value: +"The policy entrypoint to evaluate for each input, e.g. `\"authz/allow\"`. `opa exec` names a decision by slash-separated path with no `data.` prefix; the Rego reference forms (`data.authz.allow`, `authz.allow`) are accepted here and converted, because passing one straight through leaves every file undefined."
- Changed
opa_get_data2 fields changed- added
Input schema / properties / segmentsAdded value: +{ + "description": "Path as literal key segments, e.g. [\"labels\", \"app.kubernetes.io/name\"]. Use instead of `path` when a key contains a dot or a slash.", + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "path" -]
- Changed
opa_get_policy1 field changed- added
Input schema / properties / includeAstAdded value: +{ + "description": "Include OPA's parsed AST alongside the source. Off by default.", + "type": "boolean" +}
- Changed
opa_list_policies3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / includeAstAdded value: +{ + "description": "Include each policy's parsed AST. Off by default; it is roughly forty times the size of the source and will exceed the response cap on all but the smallest servers.", + "type": "boolean" +} - added
Input schema / properties / includeSourceAdded value: +{ + "description": "Include each policy's Rego source. Off by default: fetch one policy with `opa_get_policy` rather than every policy at once.", + "type": "boolean" +}
- Changed
opa_patch_data3 fields changed- changed
Input schema / properties / path / descriptionPrevious value: -"Data path the patch is applied to. Use \"\" for the root."New value: +"Data path the patch is applied to." - added
Input schema / properties / segmentsAdded value: +{ + "description": "Path as literal key segments, e.g. [\"labels\", \"app.kubernetes.io/name\"]. Use instead of `path` when a key contains a dot or a slash.", + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" +} - changed
Input schema / requiredPrevious value: -[ - "path", - "operations" -]New value: +[ + "operations" +]
- Changed
opa_put_data2 fields changed- added
Input schema / properties / segmentsAdded value: +{ + "description": "Path as literal key segments, e.g. [\"labels\", \"app.kubernetes.io/name\"]. Use instead of `path` when a key contains a dot or a slash.", + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "path" -]
- Changed
opa_query_decision2 fields changed- added
Input schema / properties / segmentsAdded value: +{ + "description": "Path as literal key segments, e.g. [\"labels\", \"app.kubernetes.io/name\"]. Use instead of `path` when a key contains a dot or a slash.", + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "path" -]
- Changed
rego_bench1 field changed- changed
Input schema / properties / count / descriptionPrevious value: -"Number of benchmark iterations. Defaults to OPA's built-in default."New value: +"Number of times to repeat the benchmark (`--count N`). Defaults to OPA's built-in default of one. Every repetition is returned in `runs`; the top-level figures come from the fastest of them."
- Changed
rego_test1 field changed- changed
Input schema / properties / count / descriptionPrevious value: -"Number of times to repeat each test (`--count N`). Default is 1. Useful for measuring repeatability or catching flaky tests under load."New value: +"Number of times to repeat the suite (`--count N`). Default is 1. Useful for catching flaky tests. OPA stops at the first repetition that fails, so `repetitions` in the output reports how many actually ran, and each test is listed once carrying its worst outcome across them."
1 tool update
v0.3.0- Changed
rego_capabilities1 field changed- changed
Input schema / properties / version / descriptionPrevious value: -"A specific OPA capabilities version (e.g. \"v0.69.0\"). When neither flag is set, lists available versions."New value: +"A specific OPA capabilities version (e.g. \"v1.19.0\"). When neither flag is set, lists available versions."
5 tool updates
v0.1.20- Changed
conftest_test2 fields changed- changed
Input schema / properties / inlineConfigParser / descriptionPrevious value: -"Parser to use for `inlineConfig`. Valid values: yaml (default), json, toml, hcl1, hcl2, ini, xml, dotenv, cue, jsonnet, properties, dockerfile. Ignored when `files` is used (conftest infers the parser from each file's extension)."New value: +"Parser to use for `inlineConfig`. Valid values: yaml (default), json, toml, hcl1, hcl2, ini, xml, dotenv, cue, jsonnet, properties, edn, hocon, dockerfile. Ignored when `files` is used (conftest infers the parser from each file's extension, unless `parser` is set)." - added
Input schema / properties / parserAdded value: +{ + "description": "Force a specific parser for all input `files` via conftest's global `--parser` flag, overriding extension-based detection. Useful for files whose extension does not match their format (e.g. parse a `.tfstate` file as `json`). Valid values: yaml, json, toml, hcl1, hcl2, ini, xml, dotenv, cue, jsonnet, properties, edn, hocon, dockerfile. For `inlineConfig`, prefer `inlineConfigParser`.", + "type": "string" +}
- Changed
opa_bundle_build6 fields changed- added
Input schema / properties / bundleAdded value: +{ + "description": "Load `paths` as bundle files or root directories (`--bundle`). Required when rebuilding or re-signing an existing bundle.", + "type": "boolean" +} - added
Input schema / properties / ignoreAdded value: +{ + "description": "File/directory name patterns to ignore during loading (`--ignore`), e.g. `[\".*\"]` to skip hidden files. These are name patterns, not filesystem paths.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / pruneUnusedAdded value: +{ + "description": "Exclude dependents of entrypoints that are not reachable from them (`--prune-unused`). Most useful alongside `entrypoints`.", + "type": "boolean" +} - added
Input schema / properties / v1CompatibleAdded value: +{ + "description": "Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`). Affects the built bundle's runtime semantics.", + "type": "boolean" +} - added
Input schema / properties / verificationKeyAdded value: +{ + "description": "Path to a PEM public key (or HMAC secret file) used to re-verify an existing signed bundle during the build (`--verification-key`). Pair with `bundle: true`.", + "type": "string" +} - added
Input schema / properties / verificationKeyIdAdded value: +{ + "description": "Key ID for verification (`--verification-key-id`, OPA default `default`).", + "type": "string" +}
- Changed
opa_exec6 fields changed- changed
Input schema / properties / dataPaths / descriptionPrevious value: -"Policy and/or data file or directory paths to load. Mutually exclusive with `bundle`."New value: +"Policy and/or data file or directory paths, each loaded as an OPA bundle root (opa exec loads policy only via bundles). Mutually exclusive with `bundle`." - added
Input schema / properties / failAdded value: +{ + "description": "CI gate: report `failed: true` when any decision is undefined or errors. Mutually exclusive with `failDefined` and `failNonEmpty`.", + "type": "boolean" +} - added
Input schema / properties / failDefinedAdded value: +{ + "description": "CI gate: report `failed: true` when any decision is defined or errors. Use when a defined result means a violation. Mutually exclusive with `fail` and `failNonEmpty`.", + "type": "boolean" +} - added
Input schema / properties / failNonEmptyAdded value: +{ + "description": "CI gate: report `failed: true` when any decision result is non-empty or errors. Mutually exclusive with `fail` and `failDefined`.", + "type": "boolean" +} - added
Input schema / properties / timeoutAdded value: +{ + "description": "Per-exec evaluation timeout as a Go duration, e.g. `\"30s\"` or `\"5m\"`. Still bounded by the server subprocess timeout (OPA_MCP_TIMEOUT_MS).", + "type": "string" +} - added
Input schema / properties / v1CompatibleAdded value: +{ + "description": "Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`).", + "type": "boolean" +}
- Changed
rego_check2 fields changed- added
Input schema / properties / bundleAdded value: +{ + "description": "Load `paths` as bundle files or root directories (`--bundle`). Only valid with `paths`, not inline `source`.", + "type": "boolean" +} - added
Input schema / properties / maxErrorsAdded value: +{ + "description": "Maximum number of errors to collect before `opa check` aborts compilation (`--max-errors`, OPA default 10). Raise it to surface more diagnostics from a badly broken policy in a single pass.", + "minimum": 1, + "type": "integer" +}
- Changed
rego_test2 fields changed- added
Input schema / properties / explainAdded value: +{ + "description": "Add a query-explanation trace to test records (`--explain`). `fails` traces only failing tests, `full` traces everything, `notes` surfaces `trace()` notes, `debug` is most verbose. Populates each record's `trace` field; pair with `verbose: true` for the human-readable trace output too.", + "enum": [ + "fails", + "full", + "notes", + "debug" + ], + "type": "string" +} - added
Input schema / properties / v1CompatibleAdded value: +{ + "description": "Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`).", + "type": "boolean" +}
3 tool updates
v0.1.17- Added
rego_playground_share - Changed
rego_test4 fields changed- added
Input schema / properties / bundleAdded value: +{ + "description": "Load paths as OPA bundle roots (`--bundle`). Required when testing policies structured as bundles with a `manifest.json` at the root. Not needed for plain policy directories.", + "type": "boolean" +} - added
Input schema / properties / countAdded value: +{ + "description": "Number of times to repeat each test (`--count N`). Default is 1. Useful for measuring repeatability or catching flaky tests under load.", + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / ignorePatternsAdded value: +{ + "description": "Glob patterns for files to exclude from the test run (`--ignore <pattern>`). Pass one pattern per array element. Useful for excluding generated or fixture files that contain no tests (e.g. `[\"*_generated.rego\", \"fixtures/**\"]`).", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / timeoutAdded value: +{ + "description": "Per-test timeout as a Go duration string, e.g. `\"30s\"` or `\"2m\"` (`--timeout`). OPA's default is 5s. Increase for tests that load large policy sets or call slow built-ins.", + "type": "string" +}
- Added
rego_test_multiroot
1 tool update
v0.1.14- Added
rego_explain_undefined
45 tool updates
v0.1.13- Added
conftest_pull - Added
conftest_push - Added
conftest_test - Added
conftest_verify - Added
mcp_server_info - Added
opa_bundle_build - Added
opa_bundle_sign - Added
opa_bundle_verify - Added
opa_compile_query - Added
opa_config - Added
opa_delete_data - Added
opa_delete_policy - Added
opa_exec - Added
opa_get_data - Added
opa_get_policy - Added
opa_health - Added
opa_list_policies - Added
opa_patch_data - Added
opa_put_data - Added
opa_put_policy - Added
opa_query_decision - Added
opa_status - Added
rego_bench - Added
rego_capabilities - Added
rego_compile_query - Added
rego_coverage_gaps - Added
rego_deps - Added
rego_describe_policy - Added
rego_eval - Added
rego_eval_with_coverage - Added
rego_eval_with_explain - Added
rego_eval_with_profile - Added
rego_explain_decision - Added
rego_fix - Added
rego_format_write - Added
rego_generate_test_skeleton - Added
rego_infer_input_schema - Added
rego_inspect - Added
rego_migrate_v1 - Added
rego_parse_ast - Added
rego_policy_diff - Added
rego_security_audit - Added
rego_suggest_fix - Added
rego_test - Added
rego_verify
4 tool updates
- Added
rego_check - Added
rego_check_schema - Added
rego_format - Added
rego_lint
32 tool updates
v0.1.5- Removed
opa_bundle_build - Removed
opa_bundle_sign - Removed
opa_compile_query - Removed
opa_config - Removed
opa_delete_policy - Removed
opa_get_data - Removed
opa_get_policy - Removed
opa_health - Removed
opa_list_policies - Removed
opa_patch_data - Removed
opa_put_data - Removed
opa_put_policy - Removed
opa_query_decision - Removed
opa_status - Removed
rego_bench - Removed
rego_capabilities - Removed
rego_check - Removed
rego_compile_query - Removed
rego_deps - Removed
rego_describe_policy - Removed
rego_eval - Removed
rego_eval_with_coverage - Removed
rego_eval_with_explain - Removed
rego_eval_with_profile - Removed
rego_explain_decision - Removed
rego_format - Removed
rego_generate_test_skeleton - Removed
rego_inspect - Removed
rego_lint - Removed
rego_parse_ast - Removed
rego_suggest_fix - Removed
rego_test
32 tool updates
v0.1.2- Added
opa_bundle_build - Added
opa_bundle_sign - Added
opa_compile_query - Added
opa_config - Added
opa_delete_policy - Added
opa_get_data - Added
opa_get_policy - Added
opa_health - Added
opa_list_policies - Added
opa_patch_data - Added
opa_put_data - Added
opa_put_policy - Added
opa_query_decision - Added
opa_status - Added
rego_bench - Added
rego_capabilities - Added
rego_check - Added
rego_compile_query - Added
rego_deps - Added
rego_describe_policy - Added
rego_eval - Added
rego_eval_with_coverage - Added
rego_eval_with_explain - Added
rego_eval_with_profile - Added
rego_explain_decision - Added
rego_format - Added
rego_generate_test_skeleton - Added
rego_inspect - Added
rego_lint - Added
rego_parse_ast - Added
rego_suggest_fix - Added
rego_test
TDQS
Scored across 52 tools
The toolset spans many domains, but several clusters blur boundaries: rego_eval/opa_exec/opa_query_decision/rego_compile_query/opa_compile_query all evaluate or compile policies in different local/server contexts, and rego_eval_with_explain/rego_explain_decision/rego_explain_undefined overlap in tracing. opa_config and opa_status return the same configuration document under different keys, adding a redundant choice. Descriptions mitigate much of this, so the set is manageable but not cleanly disambiguated.
Names consistently use snake_case with clear domain prefixes (rego_, opa_, conftest_, mcp_), which creates predictable grouping. However, several names use noun/state forms (rego_capabilities, rego_deps, opa_health, mcp_server_info) rather than a strict verb_noun pattern, and the eval/explain variants append qualifiers, so naming is mostly rather than fully consistent.
52 tools is far beyond the 3-15 well-scoped range and triggers the rubric's 50+ extreme-mismatch category. Although OPA is broad, many tools are narrow variants (three explain/eval flavors, separate local/server compile, format vs format_write, etc.), so the surface is bloated rather than each tool earning a distinct place.
Coverage is excellent: policy CRUD and data CRUD on the server, local authoring/format/lint/check/test/coverage/benchmark, bundle build/sign/verify, Conftest integration, schema inference/validation, migration, diff, and formal verification. Almost every lifecycle stage an OPA agent would need has a tool; any missing pieces (e.g., server start/stop) are plausibly out of scope.
Maintenance
Related MCP Connectors
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Authenticated MCP server for ClearPolicy policy and compliance workflows.
MCP Server for Slima - AI Writing IDE for Novel Authors with AI Beta Reader.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP Server that enables natural language interaction with the Open Policy Agent REST API, allowing users to manage policies, decisions, and data through conversational interfaces.1-
- AlicenseNot gradedqualityCmaintenanceA Model Context Protocol (MCP) server that provides safe, read-only access to Kubernetes resources for debugging and inspection. Built with security in mind, it offers comprehensive cluster visibility without modification capabilities.43MIT
- AlicenseNot gradedqualityCmaintenanceMCP server to lint and validate Kubernetes-related manifests(Helm, FluxCD, ArgoCD, Kustomize, etc.)MIT
- AlicenseBqualityDmaintenanceA specialized MCP server that provides expert-level OpenFGA authorization modeling guidance, enabling users to create and manage authorization models for ReBAC systems directly from VS Code.29MIT