OPA MCP

io.github.OrygnsCode由 GitHub 账号 OrygnsCode 发布v0.9.1更新于 Oct 27, 2026

Author, validate, debug, and explain OPA Rego policies through any MCP-compatible client.

已验证STDIO仅桌面开发者工具安全与监控

概览

AI 生成的概览

让助手编写、格式化、检查、测试、调试和解释 OPA Rego 策略,并管理运行中 OPA 服务器上的策略与 bundle。

可以做什么
  • 编写与分析 Rego:格式化、类型检查、按 JSON Schema 校验、用 Regal 检查、解析为 AST、检查 bundle、列出 capabilities、分析依赖、从 v0 迁移到 v1
  • 求值与测试:对策略和输入执行查询、完整追踪解释、性能剖析、覆盖率、单元测试、基准测试、部分求值、多文件批量执行
  • 调试与改进:解释决策为何被拒绝或未定义、概述策略结构、给出修复建议、生成测试骨架、找出覆盖缺口、安全审计、比较两份策略、自动应用机械性修复
  • 构建与签名 bundle:把策略目录打包为 .tar.gz、签名、验证签名
  • 管理运行中的 OPA 服务器:列出、获取、上传和删除策略;读取、写入、打补丁和删除数据;查询决策;健康检查、状态与配置
  • 测试配置文件:用 conftest 检查 Kubernetes、Terraform、Helm 和 Dockerfile 配置
适用场景
适合处理 Open Policy Agent 策略的场景:希望助手起草、校验、测试或调试 Rego,或查看和修改运行中 OPA 实例上的策略与数据,而不必切回命令行。
运行要求
通过 npx 或 Docker 以 stdio 在本地运行。需要 opa 可执行文件(OPA_BINARY 或 PATH 中;npm 在部分平台和 Docker 镜像自带)。Regal(REGAL_BINARY)用于 lint、修复和安全审计;conftest(CONFTEST_BINARY)用于 conftest 工具。opa_* 工具需用 OPA_URL 指向运行中的 OPA 服务器,若该服务器要求认证则需 OPA_TOKEN。文件类工具需先用 OPA_MCP_ALLOWED_PATHS 列出绝对目录。GITHUB_TOKEN(gist 权限)仅用于 playground 分享。
安装前请注意
部分工具会写磁盘:rego_format_write 和 rego_fix 会就地修改文件,bundle 签名会写入目录。opa_* 工具可在真实 OPA 服务器上上传、替换、删除策略,以及写入、打补丁或删除数据,建议先指向非生产实例。OPA_TOKEN 与 GITHUB_TOKEN 属机密;OPA_MCP_PASSTHROUGH_ENV 中的变量可被被求值的策略通过 opa.runtime().env 读取。除非设置 OPA_MCP_NO_TELEMETRY,否则会发送匿名启动 ping。

安装

在 SourceWeft 中

  1. 打开 控制台中的 OPA MCP,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

OPA MCP Server

[CI] [CodeQL] [npm version] [Docker pulls] [OPA Ecosystem] [License: MIT] [Node.js] [opa-mcp-server 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.9.1. Tool surface, error codes, and environment variables follow SemVer from v0.1.0 forward.

Upgrading to 0.9.0: a tool refuses an argument it does not declare, and the error names it; it used to be dropped. A policy or query that does not compile is INVALID_REGO in every tool that runs opa, where several returned EVAL_ERROR. rego_explain_decision returns the trace as readable lines, not OPA's raw events. conftest_test reports a run that evaluated no rule as passed: false, and rego_generate_test_skeleton writes todo_test_ stubs, which opa test skips until they are filled in. Responses are compact JSON.

Upgrading to 0.8.0: opa_exec loads dataPaths as opa eval --data does, so a directory that also holds test fixtures, or JSON and YAML that is not data, can now fail to load; pass it as bundle to load it as before. A policy that does not load is INVALID_REGO in opa_exec and the conftest tools, where it was EVAL_ERROR and UNKNOWN_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, on and off in data files are strings now, not booleans. If you supply your own binary via OPA_BINARY or PATH, only the Node requirement applies.

Upgrading to 0.6.0: rego_bench reports iterations, nsPerOp, allocsPerOp and bytesPerOp. The fields opa prints (N, T, Bytes, MemAllocs, MemBytes, Extra) were top-level and now sit under raw for a single run, so anything that read them from the top level has to look there. With count above one, raw is omitted: every document is in runs, and fastest indexes 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().env will no longer see it; name the variable in OPA_MCP_PASSTHROUGH_ENV if 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 (if is required before a rule body, contains before a partial set). Run rego_migrate_v1 to convert them, or pass v0Compatible: true to load one as it is. If you supply your own binary via OPA_BINARY or PATH, nothing changes.


Table of contents

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 fmt and opa parse so output is byte-identical to what you'd get on the command line, and regal (optional) surfaces idiomatic suggestions.
  • Evaluate against data. Run a query against a policy and an input document. Optional --explain, --profile, and --coverage flags surface execution traces, hot rules, and per-line coverage.
  • Debug a deny. rego_explain_decision walks 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 --server or 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.gz the agent can hand to your delivery system.
  • Lint. rego_lint runs 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_eval gets 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, and rego_suggest_fix compose 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):

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 substitute C:\\path\\to\\opa.exe.

Or download opa-mcp.mcpb from the latest release and double-click it.

Claude Code (CLI)

Register the server for the current project with claude mcp add:

bash
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-mcp

This 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.exe syntax.

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 the hooks block into .claude/settings.json. Runs opa check after Claude writes or edits a .rego file and hands any error back to Claude, 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)

bash
npm install -g @orygn/opa-mcpopa-mcp --version

then point your client at the opa-mcp binary.

Docker

bash
docker pull orygn/opa-mcp:latestdocker run --rm -i \  -v /path/to/your/policies:/policies:ro \  -e OPA_MCP_ALLOWED_PATHS=/policies \  orygn/opa-mcp

The 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:

bash
which opa && which regal                                    # macOS / Linux
powershell
Get-Command opa, regal | Select-Object Source              # Windows

This 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.

VariableDefaultPurpose
OPA_URLhttp://localhost:8181Base URL of an OPA REST endpoint, used by opa_* tools.
OPA_TOKEN(unset)Bearer token for OPA, if your instance requires auth. Treated as a secret. Never echoed in logs or tool responses.
OPA_BINARYopa (on PATH)Path to the opa CLI, used by rego_* tools.
REGAL_BINARYregal (on PATH)Path to the regal linter. Required by rego_lint, rego_fix, and rego_security_audit.
CONFTEST_BINARYconftest (on PATH)Path to the conftest binary. Only required by conftest_* tools. Returns CONFTEST_NOT_FOUND if absent.
OPA_MCP_ALLOWED_PATHS(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.
OPA_MCP_LOG_FILE<tmpdir>/orygn-opa-mcp.logPath the server appends logs to. The server never writes to stdout; that channel is reserved for the MCP protocol.
OPA_MCP_LOG_LEVELinfoOne of debug, info, warn, error.
OPA_MCP_MAX_RESPONSE_BYTES100000Hard cap on a single tool response. Larger payloads are truncated with a __truncated: true marker. Values below 512 are refused.
OPA_MCP_TIMEOUT_MS30000Hard timeout for any spawned subprocess (opa, regal). After this, the child gets SIGTERM and then SIGKILL.
OPA_MCP_HTTP_TIMEOUT_MS15000Timeout for each request to the OPA REST API, from the connection attempt to the last byte of the response; reported as TIMEOUT.
OPA_MCP_NO_TELEMETRY(unset)Set to 1 to disable the anonymous startup ping. The ping sends the server version, OS platform, and a random install ID, stored at ~/.orygn/opa-mcp/install-id; containers and CI jobs send a container or ci label instead. No policy content or file paths are ever sent.
OPA_MCP_MAX_SUBPROCESS_BYTES33554432 (32 MiB)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 OUTPUT_TOO_LARGE. Distinct from OPA_MCP_MAX_RESPONSE_BYTES, which trims the reply after the output is already in memory.
OPA_MCP_PASSTHROUGH_ENV(unset)Comma-separated variable names to pass through to opa, regal and conftest. Everything else is withheld. Anything named here is readable by any policy the server evaluates, via opa.runtime().env, so use it only for values that are safe in that position.
OPA_MCP_BLOCK_ENV(unset)Comma-separated variable names to withhold from opa, regal and conftest even when they are on the built-in allow-list. Applied last, so it also overrides OPA_MCP_PASSTHROUGH_ENV. Use it to drop the proxy variables, which can carry credentials, at the cost of proxy support.

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:

json
{ "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.

ToolWhat it does
rego_formatFormat Rego source. Wraps opa fmt. Idempotent.
rego_checkType-check and validate Rego. Wraps opa check.
rego_lintRun Regal across a file or directory. Returns each violation with its category, level and location. Requires regal on PATH or REGAL_BINARY set.
rego_parse_astParse Rego to AST JSON. Wraps opa parse.
rego_inspectInspect a bundle or directory: packages, rules, annotations. Wraps opa inspect.
rego_capabilitiesList the built-ins and features the resolved opa binary understands (OPA_BINARY, then PATH, then the bundled copy); builtins names up to 100 to return full records for
rego_depsStatic dependency analysis: rule-level data references and cross-package calls.
rego_migrate_v1Migrate Rego v0 source to v1. Renames a rule v1 reserves the name of (contains, every, if, in) and replaces the built-ins v1 removed, with exact equivalents, before opa fmt --rego-v1 converts the syntax and opa check validates it. Given inputs, evaluates the original as v0 and the result as v1 on each and reports any rule that differs, plus any queries, which is how functions are compared. Returns { original, migrated, changed, valid, errors, rewrites, notes, equivalence }. dataPaths loads the data the policy reads for that comparison.
rego_check_schemaCheck Rego against a JSON Schema. Validates that every input.* field the policy reads exists in the schema using opa check --schema. Accepts an inline schema, a path to a JSON Schema file, or a schema directory when the policy declares schemas: annotations.
Featured: rego_format
jsonc
// 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
jsonc
// 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.

ToolWhat it does
rego_evalEvaluate a query against a policy and input. The bread-and-butter tool. inputs evaluates the query against up to 50 input documents in one call and reports each; with no policy, a query alone tries out a built-in or an expression. Each result says whether the query was defined, and print() output comes back in printed.
rego_eval_with_explainEvaluate with --explain=full and return OPA's raw trace events. rego_explain_decision renders the same trace as readable lines.
rego_eval_with_profileEvaluate with --profile and return per-rule timing and evaluation counts.
rego_eval_with_coverageEvaluate with --coverage and return per-line coverage.
rego_testRun Rego unit tests with opa test. Returns pass, fail, skip and error counts plus per-test records; errored counts tests OPA could not evaluate. coverage or threshold also adds the coverage report, unless a test fails or errors. allPassed is true only when at least one test ran and none failed, errored or was skipped.
rego_benchRun opa bench and return statistical timing data.
rego_compile_queryPartially evaluate a query against a policy.
opa_execBatch-evaluate a decision against multiple input files. Returns per-file results with successCount and errorCount. dataPaths load as opa eval --data loads them; bundle takes a bundle.
rego_test_multirootRun opa test once per root and aggregate. Use when opa test . hits package conflicts. Totals include totalErrored.
Featured: rego_eval
jsonc
// 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.

ToolWhat it does
opa_bundle_buildBuild a .tar.gz bundle from a policy directory. Supports optimize and revision.
opa_bundle_signSign 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 opa_bundle_build. A directory signature stays valid wherever the directory is placed under the same name. Returns the path, algorithm, and file count.
opa_bundle_verifyVerify a signed bundle with a public key through opa build --verification-key. Failures name the reason: wrong key, scope, modified, added, missing or unparseable file, unsigned, or a bundle that does not load.

Category D: OPA server management

Talk to a running OPA server over its REST API. Require OPA_URL to point at a reachable server.

ToolWhat it does
opa_list_policiesList the policy IDs registered on the server, with a count. includeSource and includeAst add the Rego text or the parsed AST.
opa_get_policyGet a single policy by ID. Returns the Rego source; includeAst adds OPA's parsed AST.
opa_put_policyUpload or replace a policy; replaced says whether one existed. A policy that does not compile returns INVALID_REGO with OPA's errors and is not stored.
opa_delete_policyDelete a policy by ID.
opa_get_dataRead a path from the data hierarchy.
opa_put_dataWrite to a path in the data hierarchy.
opa_patch_dataApply a JSON Patch to the data hierarchy.
opa_delete_dataDelete a document from the data hierarchy.
opa_query_decisionPOST to a /v1/data/... decision endpoint with input. defined: false means the path produced no value, which is not the same as false.
opa_compile_queryPartially evaluate a query against the running server.
opa_healthLiveness / readiness check. A server that answers reports healthy: true or healthy: false with OPA's reason; OPA_UNREACHABLE means it could not be reached at all.
opa_statusThe same GET /v1/config document as opa_config, under a status key. Bundle and decision-log status (/v1/status) is not exposed. Service header values are redacted.
opa_configServer configuration from GET /v1/config. OPA drops the credentials block but returns service headers verbatim, so header values are redacted here and the names kept.

Category E: Higher-level helpers

The differentiation surface. These compose lower-level primitives into the tasks agents are actually asked to do.

ToolWhat it does
rego_explain_decisionEvaluate with full tracing and return the rules entered and fired, plus the trace as readable lines. The Fail lines name the condition that stopped a rule.
rego_generate_test_skeletonGiven a policy, generate a _test.rego skeleton with one stub per rule. Stubs are todo_test_ rules, which opa test reports as skipped until they are filled in and renamed test_.
rego_describe_policySummarize a policy's package, imports and per-rule structure from its AST. For the input references a policy reads, use rego_infer_input_schema
rego_suggest_fixPass errors from rego_check or violations from rego_lint unchanged; returns a fix suggestion per diagnostic with a confidence level, and the rule's documentation link where there is one.
rego_coverage_gapsRun opa test --coverage and return per-file uncovered line ranges, sorted worst first. Use threshold to focus on files below a target percentage.
rego_security_auditRun regal lint restricted to its bugs category, plus any custom rules in a security category, across a directory. Returns severity-grouped findings with remediation guidance. Modules that do not parse are listed in unparseable and the rest are audited.
rego_infer_input_schemaStatically analyse a policy (or directory of policies) with opa parse and return a JSON Schema describing every input.* field the policy reads. Follows loop variables, rules and function parameters bound to part of the input, so some c in input.containers then c.image gives input.containers[].image. A type is set only where the policy shows it. No running OPA required. A starting point for test inputs or a rego_check_schema schema; review it first.
rego_fixRun regal fix to auto-apply mechanical fixes. Regal 0.42 and later fix 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 first. Returns a per-file breakdown of which rules were applied and, for directory-package-mismatch, the new path the file was moved to.
rego_format_writeRun opa fmt --write to canonically format one or more Rego files or directories in place. Use dryRun: true to list which files would change without modifying them. Validates all files parse successfully before writing any. Supports regoV1, v0Compatible, and v1Compatible flags. Only requires opa.
rego_policy_diffEvaluate the same query against two policies in parallel and compare the results. Returns equal: true/false, the raw value from each side (resultA/resultB), and changedPaths -- dot/bracket JSON paths that differ. Each side takes inline source or a file/directory path. Useful for verifying refactor equivalence or mapping divergence between two policy versions. inputs compares the two on up to 50 input documents in one call and returns batch, one entry per input, with differing counting the inputs on which they disagree.
rego_verifyFormally 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 kind field takes always_true, never_true or satisfiable. Handles equality, comparison, string built-ins (startswith, endswith, contains, regex.match), multi-clause rules, rule defaults, non-boolean head values, and cross-rule inlining. Reports INCONCLUSIVE rather than guessing for negation-as-failure, comprehensions, partial set and object rules, functions, else chains, and complex regex. A body reading an absent field is undefined rather than true, so always_true requires the rule to hold for an empty input too.
rego_explain_undefinedExplain why a Rego query is undefined, fell back to its default, or (for a set such as deny) holds no element. 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.
rego_playground_sharePublish a policy (and optional input) as a secret GitHub Gist (pass public: true to list it) and return the link, for sharing a reproduction. Requires GITHUB_TOKEN with the gist scope; returns GITHUB_TOKEN_MISSING otherwise.

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.

ToolWhat it does
conftest_testEvaluate config files or an inline document against Rego policies with conftest test. Per-file, per-namespace results with arrays always present, and a summary that counts files by name. Parser names are a closed set. A run that evaluated no rule (wrong namespace, or no deny/violation/warn rules) is reported as passed: false with nothingEvaluated: true, where conftest itself exits 0.
conftest_verifyRun the test_* rules in a conftest policy directory with conftest verify. Reports per-rule results and NO_TESTS_FOUND when there are none.
conftest_pullPull a policy bundle from an OCI registry or Git repo into a local directory with conftest pull. The target directory need not exist; conftest creates it, and empties it first, so do not point it at one holding anything else. Omitting policy uses the conftest default, which must itself sit inside an allowed root.
conftest_pushPackage a local policy directory as an OCI artifact and push to a registry with conftest push. Registry credentials come from the host environment (docker login, ORAS keychain, etc.) -- credentials are never passed through tools.
Featured: conftest_test with inline config
jsonc
// 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

ToolWhat it does
mcp_server_infoReturn server name, version, resolved opa/regal/conftest versions, transport type, and Node.js version in one call. Useful for verifying which server instance the agent is connected to.

Prompts

Three MCP prompts ship with the server. Clients surface them as slash commands or workflow templates.

PromptPurpose
policy_authoring_assistantWalks the agent through writing a new policy: ask about the decision surface, draft, review, format, lint, test.
policy_review_checklistReview checklist for an existing policy: completeness, edge cases, performance, security pitfalls.
decision_debugging_workflowDiagnostic 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 URIWhat's there
opa://builtinsCategorized OPA built-in function reference, derived at read time from opa capabilities --current. Security-sensitive functions (http.send, crypto.x509.*, opa.runtime) are flagged.
opa://style-guideCondensed Rego style guide, formatted for LLM consumption.
opa://patternsCurated 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: (calls rego_eval with an `inputs` batch: each role, no role at all,       a role that is not a string, an unknown method)
Agent: Here's the policy. A request with no role, or a role that is not a       string, is denied. I kept those probes as tests next to one case per       role. (calls rego_generate_test_skeleton, fills in the stubs, 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:

  1. stdout is the protocol channel. The server logs to a file via lib/logger.ts and never writes to stdout. If you see stray stdout bytes, the client disconnects; the MCP transport layer is strict.

  2. 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 with isError: true whose text begins MCP 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 a try/catch that could not see it.

  3. Subprocesses are bounded in time, size, and environment. lib/subprocess.ts runs the binaries with shell: false, a hard timeout with SIGTERM-then-SIGKILL escalation, 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: opa buffers 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.

  4. Children do not inherit the server's environment. lib/child-env.ts builds an explicit allow-list instead. Rego can read its interpreter's environment through opa.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 return PATH_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 opa process through opa.runtime().env, so a child that inherited process.env would hand OPA_TOKEN, GITHUB_TOKEN, and every other variable to any policy it evaluated. Since rego_eval accepts 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_PROXY and 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 in OPA_MCP_BLOCK_ENV to withhold them anyway. OPA_MCP_PASSTHROUGH_ENV opts individual variables back in.
  • OPA_TOKEN is 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_eval and its variants, rego_test, rego_test_multiroot, rego_bench, rego_compile_query, opa_exec, rego_migrate_v1 (when given inputs), 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's http.send lets a policy reach, and write to, any network address. A client that gates on the hints will ask before running one. opa_query_decision and opa_compile_query are 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, so http.send cannot be restricted for evaluation; rego_check and opa_bundle_build accept 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 of opa and regal checked 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:

bash
# macOS / Linuxwhich opa# → /usr/local/bin/opa  (or /opt/homebrew/bin/opa, or ~/.local/bin/opa)
powershell
# WindowsGet-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

bash
git clone https://github.com/OrygnsCode/opa-mcp-server.gitcd opa-mcp-servernpm installnpm run dev

Common commands:

bash
npm run lint              # ESLintnpm run typecheck         # tsc --noEmitnpm test                  # unit tests (Vitest)npm run test:coverage     # unit + coverage reportnpm run test:integration  # against real opa + regal binariesnpm 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

MIT © Orygn LLC

@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.

来源:README.md,提交 34ce42f

工具

52

rego_format

Format Rego

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).

输入参数source必填v0Compatible

rego_check

Check Rego

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.

输入参数pathsbundlesourcestrictmaxErrorsschemaDircapabilitiesv0Compatible

rego_check_schema

Check Rego against a JSON Schema

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.

输入参数pathssourcestrictschemaPathinlineSchemav0Compatible

rego_lint

Lint Rego

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.

输入参数pathsenablesourcedisablefailLevelconfigFileignoreFilesenableCategorydisableCategory

rego_parse_ast

Parse Rego to AST

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.

输入参数source必填v0Compatible

rego_inspect

Inspect bundle or policy

Inspect an OPA bundle, policy directory, or single Rego file with `opa inspect`. Returns manifest data, namespaces, rule annotations, and (if signed) signature metadata.

输入参数target必填v0Compatible

rego_capabilities

OPA capabilities

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.

输入参数currentversionbuiltinsnames_only

rego_deps

Rego dependency analysis

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.

输入参数ref必填paths必填

rego_migrate_v1

Migrate Rego to v1 syntax

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.

输入参数inputssource必填queriesdataPaths

rego_eval

Evaluate Rego query

Evaluate a Rego query against a policy and an input document using `opa eval`. Returns the standard `{result: [...]}` shape plus `defined`, which is false when the query produced no value (undefined is not `false`), and `printed`, the lines the policy wrote with `print()`. 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.

输入参数inputpathsquery必填inputssourcepartialunknownsinputPathv0CompatiblestrictBuiltinErrors

rego_eval_with_explain

Evaluate Rego with execution trace

Evaluate with `--explain=full` and return OPA's raw trace events (with their AST nodes) alongside the result. For a readable trace use `rego_explain_decision`, which renders the same events as lines. Raw events are large: over the response cap the bound-variable values are dropped first, then trailing events (`explanationTruncated`), and the result is kept.

输入参数inputpathsquery必填sourcepartialunknownsinputPathv0CompatiblestrictBuiltinErrors

rego_eval_with_profile

Evaluate Rego with profiling

Evaluate with `--profile` and return per-rule timing and evaluation counts. Use this to find hot rules in slow policies.

输入参数inputpathsquery必填sourcepartialunknownsinputPathv0CompatiblestrictBuiltinErrors

rego_eval_with_coverage

Evaluate Rego with coverage

Evaluate with `--coverage` and return per-line coverage data. Useful for verifying that tests actually exercise the rules they're meant to.

输入参数inputpathsquery必填sourcepartialunknownsinputPathv0CompatiblestrictBuiltinErrors

rego_test

Run Rego tests

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.

输入参数countpaths必填bundleexplaintimeoutverbosecoveragethresholdvarValuesrunPatternv0Compatiblev1Compatible另有 1 个

rego_test_multiroot

Run Rego tests across multiple roots

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.

输入参数rootsscanDirverbosecoveragemaxDepthmaxRootsthresholdvarValuesrunPatternsharedPathsv0CompatibleignorePatterns

rego_bench

Benchmark Rego query

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.

输入参数countinputpathsquery必填inputPathv0Compatible

rego_compile_query

Partially evaluate a Rego query

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.

输入参数inputpathsquery必填sourcepartialunknownsinputPathv0CompatiblestrictBuiltinErrors

opa_exec

Batch-evaluate OPA policy against input files

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.

输入参数failbundletimeoutdecision必填dataPathsinputPaths必填failDefinedfailNonEmptyv0Compatiblev1Compatible

opa_bundle_build

Build OPA bundle

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.

输入参数paths必填bundleignoreoutput必填targetoptimizerevisionclaimsFilesigningAlgsigningKeyentrypointspruneUnused另有 5 个

opa_bundle_sign

Sign OPA bundle

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.

输入参数bundle必填claimsFilesigningAlgsigningKey必填

opa_bundle_verify

Verify OPA bundle signature

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.

输入参数scopebundle必填signingAlgv0CompatibleverificationKey必填verificationKeyId

opa_list_policies

List OPA policies

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.

输入参数includeAstincludeSource

opa_get_policy

Get OPA policy by ID

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.

输入参数id必填includeAst

opa_put_policy

Upload or replace OPA policy

Upload a Rego policy under the given ID. Replaces any existing policy with that ID; `replaced` says whether one existed. The policy is uploaded as raw text/plain and OPA compiles it on the server, so a policy that does not compile comes back as INVALID_REGO with OPA's errors, and nothing is stored.

输入参数id必填source必填

opa_delete_policy

Delete OPA policy

Delete a policy by ID from the running OPA server.

输入参数id必填

opa_get_data

Read data from OPA

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.

输入参数pathsegments

opa_put_data

Write data to OPA

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.

输入参数pathvaluesegments

opa_patch_data

Patch data on OPA

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.

输入参数pathsegmentsoperations必填

opa_delete_data

Delete a data document from OPA

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.

输入参数pathsegments

opa_query_decision

Query OPA decision

Evaluate a decision against the running OPA server. POSTs to the data path with `{input}` and returns whatever the rule produces, plus `defined`: false when the path produced no value, which OPA reports by leaving `result` out. Undefined is not `false`; a caller that treats it as false or as allow decides on something the policy never said. Use this to ask the server "given this input, what does data.X.allow say?"

输入参数pathinputexplainmetricssegments

opa_compile_query

Compile (partially evaluate) a query on OPA

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.

输入参数inputquery必填unknowns

opa_health

OPA health check

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.

输入参数bundlesplugins

opa_status

OPA status

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.

无需输入参数。

opa_config

OPA configuration

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.

无需输入参数。

rego_explain_decision

Explain Rego decision

Evaluate a Rego query with full tracing and return the result, the rules entered (`rulesEvaluated`) and those that produced a value (`rulesFired`), and the trace as readable lines: location, nesting, operation, the expression in Rego syntax, and the values of the variables it names. Backtracking (Redo) events are left out. Use it to answer "why was this denied?" or "why did this rule not match?": the `Fail` lines name the condition that stopped a rule. A trace too long for the response cap is cut from the end (`traceTruncated`); narrow the query or the input to see the rest.

输入参数inputpathsquery必填sourcepartialunknownsinputPathv0CompatiblestrictBuiltinErrors

rego_explain_undefined

Explain why a Rego query is undefined

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. A multi-value rule such as `deny contains msg if ...` that holds no element reports `empty` with the same breakdown, which answers "why was this not denied". Returns a structured breakdown of which conditions blocked each rule plus a human-readable summary. `paths` may name directories, which are searched for the modules that declare the queried package.

输入参数inputpathsquery必填sourceinputPathv0Compatible

rego_generate_test_skeleton

Generate Rego test skeleton

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. Every stub is a `todo_test_` rule, which `opa test` reports as skipped (and exits non-zero for) until a realistic input and the expected value are filled in and it is renamed `test_`: a placeholder input against a placeholder expectation would otherwise pass while testing nothing. 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.

输入参数source必填tableStylev0Compatible

rego_describe_policy

Describe Rego policy

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.

输入参数source必填v0Compatible

rego_suggest_fix

Suggest fix for Rego diagnostics

Map common Rego compile errors and Regal lint findings to fix suggestions. Pass `errors` from `rego_check` or `violations` from `rego_lint` unchanged. Returns one suggestion per diagnostic; confidence is `high` for well-known patterns, `medium` where the answer is the rule's documentation (`docs`), `low` for everything else.

输入参数diagnostics必填

rego_coverage_gaps

Rego test coverage gaps

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.

输入参数paths必填thresholdrunPatternv0Compatible

rego_security_audit

Rego security audit

Run regal lint restricted to its `bugs` category plus any custom rules placed in a `security` category, across one or more policy directories, and return the findings grouped by severity (high/medium) with remediation guidance and a link to each rule. Use it for a periodic fleet-wide sweep rather than per-file style review. Modules that do not parse are listed in `unparseable` and the rest are audited. These are lint findings: a policy with none can still let a request through, so probe it with `rego_eval` inputs (absent, null and wrong-typed fields) for that. Requires regal.

输入参数paths必填configFileignoreFiles

rego_infer_input_schema

Infer input schema

Statically analyse one or more Rego policies and return a JSON Schema (draft-07) object describing every input.* field the policies read. It follows the ways a policy reads input: loop variables (`some c in input.containers` then `c.image`), rules whose value is an input path (`pod_spec := input.request.object.spec`), function parameters (`trusted(c)`) and `object.get` keys. A key the policy computes is left open, and a scalar type is set only where a comparison with a literal, an `is_*` check or a string built-in shows it. Uses opa parse -- no running OPA server required. A starting point for test inputs and for a schema to give rego_check_schema; review it first, since types the policy never shows are left out. Accepts inline source, individual files, or directories (walked recursively for *.rego files).

输入参数pathssourcev0Compatible

rego_fix

Auto-fix Rego violations

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.

输入参数forcepaths必填dryRunenabledisableconfigFileignoreFilesenableCategorydisableCategory

rego_format_write

Format Rego files in place

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.

输入参数paths必填dryRunregoV1v0Compatiblev1Compatible

rego_policy_diff

Diff two Rego policies

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; pass `inputs` to compare on many input documents in one call, and `dataPaths` to load the data the policies read.

输入参数inputpathApathBquery必填inputssourceAsourceBdataPathsinputPathv0CompatibleAv0CompatibleB

rego_verify

Formally verify a Rego policy rule

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 {}.

输入参数kind必填rule必填source必填v0Compatible

rego_playground_share

Share Rego policy as a GitHub Gist

Share a Rego policy with teammates or create a reproducible example by publishing it as a GitHub Gist, secret unless `public: true` is passed, so only people holding the link can read it. Returns { gistUrl, rawPolicyUrl, id, public }: the gistUrl renders the policy with syntax highlighting on github.com; the rawPolicyUrl can be passed directly to OPA (`opa eval -d <rawPolicyUrl> <query>`) or used as a data source in Conftest. When query, input, or data are supplied, a metadata.json file is bundled into the Gist so recipients have the full evaluation context to reproduce results. Each call creates a new Gist -- use the returned id to reference it later. Requires GITHUB_TOKEN in the environment (GitHub personal access token with the "gist" scope); returns GITHUB_TOKEN_MISSING with setup instructions if unset.

输入参数datainputquerypolicy必填publicdescription

conftest_test

Conftest test

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. A run in which no rule was evaluated (wrong `namespace`, or no `deny`/`violation`/`warn` rules) is reported as `passed: false` with `nothingEvaluated: true` and the namespaces that do hold rules, where conftest itself would exit 0.

输入参数datafilesparserpolicycombinenamespacefailOnWarninlineConfiginlinePolicyv0CompatibleallNamespacesinlineConfigParser

conftest_verify

Conftest verify

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.

输入参数datapolicynamespacev0Compatible

conftest_pull

Conftest pull

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.

输入参数url必填policy

conftest_push

Conftest push

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.

输入参数policyrepository必填v0Compatible

mcp_server_info

MCP server info

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.

无需输入参数。

版本历史

5
  1. v0.9.1最新Oct 24, 2026
  2. v0.9.0Oct 6, 2026
  3. v0.8.0Sep 28, 2026
  4. v0.7.0Sep 26, 2026
  5. v0.6.0Sep 16, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分