关于 OPA MCP
OPA MCP 是面向 Agent 和开发者的 MCP 服务,用于编写和运维 Open Policy Agent 策略。它整合 Rego 编辑、评估、调试、检查和策略管理,并提供结构化工具与精选策略资源。
主要功能
- 01生成、格式化和重构 Rego
- 02评估策略并提供跟踪、性能分析和覆盖率选项
- 03解释决策并生成测试骨架
- 04通过 OPA REST API 管理策略
- 05构建并可选签名策略包
- 06使用 Regal 检查策略
适用场景
- 01在 MCP 客户端中起草和修改 Rego 策略
- 02追踪策略拒绝请求的原因
- 03根据输入数据验证策略
- 04打包策略以供部署
MCP 相关
通过 stdio 向 MCP 客户端提供 52 个结构化工具、提示词和资源,涵盖 Rego 编写与评估、OPA REST API 操作、策略包构建和检查。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @orygn/opa-mcpOPA_URLBase URL of a running OPA server. Required only for opa_* runtime tools, not for rego_* language tools.OPA_TOKEN密钥Bearer token for OPA running with --authentication=token.OPA_BINARYPath to the opa binary. Defaults to 'opa' on PATH.REGAL_BINARYPath to the regal binary (optional; used by rego_lint, rego_security_audit and rego_fix). Defaults to 'regal' on PATH.CONFTEST_BINARYPath to the conftest binary (optional, used by conftest_* tools). Defaults to 'conftest' on PATH.OPA_MCP_ALLOWED_PATHSComma-separated list of root directories tools may read/write. When unset, file-based tools refuse to access the disk.GITHUB_TOKEN密钥GitHub personal access token with the "gist" scope. Required only for rego_playground_share.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
52收录的工具列表 · 更新于 4 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| source | string | 是 | 要格式化的 Rego 源代码。 |
| v0Compatible | boolean | 否 | 将使用 1.0 之前 Rego 编写的策略按 1.0 之前的 Rego 格式化(`--v0-compatible`),保持其语法不变。否则 OPA 1.x 会拒绝该策略。若要将其转换为 Rego v1,请使用 `rego_migrate_v1`。 |
详细介绍
OPA MCP Server
一个模型上下文协议(MCP)服务,可将任何兼容 MCP 的客户端(Claude Desktop、Claude Code、Cursor、VS Code、Windsurf、Zed 等)变为一流的 Open Policy Agent 和 Rego 编写环境。
+--------------------+ MCP/stdio +-----------------+ spawn/HTTP +---------------------+
| Claude · Cursor · |----------> | @orygn/opa-mcp |----------> | opa · regal |
| VS Code · ... |<---------- | |<---------- | conftest · REST API |
+--------------------+ 52 tools +-----------------+ +---------------------+
状态: v0.9.1。工具接口、错误代码和环境变量自 v0.1.0 起遵循 SemVer。
升级到 0.9.0: 工具现在会拒绝未声明的参数,并在错误中指出参数名称;以前这类参数会被丢弃。无法编译的策略或查询,在所有运行 opa 的工具中都会返回
INVALID_REGO;此前有些工具会返回EVAL_ERROR。rego_explain_decision现在以易读的行返回跟踪信息,而非 OPA 的原始事件。conftest_test会将未评估任何规则的运行报告为passed: false;rego_generate_test_skeleton会写入todo_test_占位测试,这些测试在补全之前会被opa test跳过。响应采用紧凑 JSON 格式。
升级到 0.8.0:
opa_exec会像opa eval --data一样加载dataPaths,因此同时包含测试夹具的目录,或非数据文件格式的 JSON 和 YAML,现在可能无法加载;如需按以前的方式加载,请将其作为bundle传入。无法加载的策略,在opa_exec和 conftest 工具中会返回INVALID_REGO;此前会返回EVAL_ERROR和UNKNOWN_ERROR。
升级到 0.7.0: 需要 Node.js 22 或更高版本。捆绑的 OPA 为 1.21,它会根据 1.2 架构读取 YAML:数据文件中的裸
yes、no、on和off现在会被视为字符串,而非布尔值。如果通过OPA_BINARY或PATH提供自己的二进制文件,则只需满足 Node.js 版本要求。
升级到 0.6.0:
rego_bench会报告iterations、nsPerOp、allocsPerOp和bytesPerOp。opa 输出的字段(N、T、Bytes、MemAllocs、MemBytes、Extra)以前位于顶层;现在,单次运行时这些字段位于raw下,因此从顶层读取这些字段的代码必须改为从此处读取。count大于 1 时会省略raw:每个文档都位于runs中,而fastest会索引顶层数据所依据的那次运行。
升级到 0.4.0: 子进程不再继承服务的环境。通过
opa.runtime().env读取变量的策略将无法再看到该变量;如果确实需要,请在OPA_MCP_PASSTHROUGH_ENV中指定该变量。原因请参阅安全章节。
升级到 0.3.0: 捆绑的 OPA 现在为 1.19,因此 Rego v0 策略将无法解析(规则体前必须有
if,部分集合前必须有contains)。请运行rego_migrate_v1进行转换,或传入v0Compatible: true按原样加载。如果通过OPA_BINARY或PATH提供自己的二进制文件,则不会有任何变化。
目录
你可以用它做什么
连接 MCP 客户端后,Agent 可以:
- 编写 Rego。 生成、格式化和重构策略。服务会运行真正的
opa fmt和opa parse,因此输出与在命令行中获得的结果逐字节一致;regal(可选)则会给出符合惯用写法的建议。 - 根据数据进行评估。 针对策略和输入文档运行查询。可选的
--explain、--profile和--coverage标志会显示执行跟踪、热点规则和逐行覆盖率。 - 调试拒绝决策。
rego_explain_decision会逐步引导 Agent 查看每条触发的规则(以及未触发的规则),让它无需手动阅读跟踪记录,也能回答“为什么被拒绝”。 - 管理运行中的 OPA 上的策略。 通过 OPA 的 REST API,在 OPA 服务上列出、获取、上传和删除策略。既适用于本地的
opa run --server,也适用于使用 bearer 令牌身份验证的生产部署。 - 构建并签名 Bundle。 将策略目录打包成可部署的 Bundle,也可选择为其签名。输出是标准的
.tar.gz文件,Agent 可以将其交给你的交付系统。 - 检查代码。
rego_lint会对目录或单个文件运行 Regal,并返回每条检查结果的类别、级别和位置。
典型会话的演练请参阅操作指南。
为什么选择这个 MCP
OPA 已经有很不错的 CLI 和 REST API。那为什么还要用 MCP 封装?
- 符合架构的工具接口。 调用
rego_eval的 Agent 会获得经过验证的输入架构、结构化输出封装和稳定的错误代码,而不必解析自由格式的 CLI 文本并自行设计错误分类。这一点本身就让 Agent 能够使用 Rego,正如语言服务器让 IDE 能够使用一种语言。 - 更高层级的辅助工具。
rego_explain_decision、rego_generate_test_skeleton、rego_describe_policy和rego_suggest_fix将底层基本功能组合起来,用于完成 Agent 实际接到的任务。OPA CLI 中没有这些功能。 - 精选知识。 内置的 MCP 资源提供 OPA 内置函数目录、官方 Rego 风格指南(针对大模型进行了排版优化),以及涵盖 RBAC、ABAC、Kubernetes 准入、IaC 门禁、API 授权和速率限制的精选模式库,因此 Agent 无需抓取资料也能获得权威上下文。
- Agent 可以依赖的安全边界。 路径允许列表、子进程超时和响应大小上限。默认设置较为保守;运行服务不会悄然赋予 Agent 超出操作员预期的权限。
如果你曾见过 Agent 被 opa eval 的参数顺序难住,就会明白这个项目填补了什么空白。
安装
服务通过 stdio 在本地运行。请选择与客户端相匹配的安装方式。
Claude Desktop
直接编辑 claude_desktop_config.json(或从
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"
}
}
}
}
请将
/usr/local/bin/...路径替换为实际路径。请参阅下文的首次安装注意事项。Windows 用户请替换为C:\\path\\to\\opa.exe。
或者,从最新版本下载 opa-mcp.mcpb,然后双击打开。
Claude Code(CLI)
使用 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-mcp
这会将配置写入项目根目录下的 .mcp.json,并在该目录中的每次 claude 会话启动时自动加载。
添加 --scope user 可改为全局注册。
将路径替换为实际的绝对路径(与上文 Claude Desktop 中的注意事项相同)。 在 Windows 上,请使用
C:\path\to\opa.exe这样的语法。
为策略仓库持久化上下文并自动检查。 如果你经常在 OPA 策略仓库中工作,以下两个额外文件可以免去每次会话的重复设置:
examples/CLAUDE.md—— 复制到仓库根目录或.claude/CLAUDE.md。Claude Code 会在每次会话中加载该文件,因此 Agent 始终知道该使用哪些工具以及适用哪些约定。examples/claude-code-hook.json—— 将hooks区块合并到.claude/settings.json。Claude 写入或编辑.rego文件后,此配置会运行opa check,并将任何错误反馈给 Claude,无需手动调用工具。
Cursor
将 examples/cursor.json 放入 .cursor/mcp.json(项目范围)或 ~/.cursor/mcp.json(用户范围)。
VS Code(GitHub Copilot Chat)
将 examples/vscode.json 放入 .vscode/mcp.json,或将 servers 区块粘贴到用户 settings.json 的 mcp.servers 下。
Windsurf、Zed 及其他
完整的即用配置请参阅 examples/。
手动安装(任何 MCP 客户端)
npm install -g @orygn/opa-mcp
opa-mcp --version
然后将客户端指向 opa-mcp 二进制文件。
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-mcp
此镜像支持多种架构(linux/amd64、linux/arm64),内置固定版本的 opa 和 regal,并以非 root 用户身份运行。无需在主机上安装 OPA 或 Regal。
⚠ 如果每次工具调用都返回 OPA_BINARY_NOT_FOUND
npm 包自带适用于其构建支持的五个平台的 opa,因此这些平台上客户端的 PATH 中没有 opa 也不受影响。MCPB 没有内置副本;在其他任何平台上,npm 包也没有:此时服务可以启动,但每次工具调用都会返回 OPA_BINARY_NOT_FOUND。npm 包和 MCPB 均未内置 regal 或 conftest,而 Docker 镜像内置了 regal,但未内置 conftest,因此无论哪种情况,这些工具都需要在 PATH 中配置路径,或显式指定路径。
**修复方法:**在客户端配置中添加 OPA_BINARY 和 REGAL_BINARY 环境变量,并为各二进制文件设置绝对路径。examples/ 下的示例配置包含需要替换的占位路径。
使用以下命令查找实际路径:
which opa && which regal # macOS / Linux
Get-Command opa, regal | Select-Object Source # Windows
这不影响 Docker 安装方式,因为镜像内置了 opa 和 regal,完全绕过 PATH。MCPB 包不包含这两个程序,与 npm 安装不同,它也没有内置回退方案:请设置 OPA_BINARY,或将 opa 放入 PATH。
详情请参阅故障排除。
配置
服务通过环境变量读取配置。所有变量均为可选项;默认值适用于运行在 http://localhost:8181 上的本地 OPA。
| 变量 | 默认值 | 用途 |
|---|---|---|
OPA_URL | http://localhost:8181 | OPA REST 端点的基本 URL,供 opa_* 工具使用。 |
OPA_TOKEN | (未设置) | OPA 的 Bearer 令牌(如果你的实例需要身份验证)。作为机密处理。绝不会在日志或工具响应中回显。 |
OPA_BINARY | opa(位于 PATH 中) | opa CLI 的路径,供 rego_* 工具使用。 |
REGAL_BINARY | regal(位于 PATH 中) | regal 代码检查工具的路径。rego_lint、rego_fix 和 rego_security_audit 必需。 |
CONFTEST_BINARY | conftest(位于 PATH 中) | conftest 二进制文件的路径。仅 conftest_* 工具需要。若不存在,则返回 CONFTEST_NOT_FOUND。 |
OPA_MCP_ALLOWED_PATHS | (未设置) | 以逗号或分号分隔的目录列表,指定服务允许从中读取策略的目录。未设置时,基于文件的工具会拒绝从磁盘读取。 |
OPA_MCP_LOG_FILE | <tmpdir>/orygn-opa-mcp.log | 服务追加写入日志的路径。服务绝不会向 stdout 写入内容;该通道专用于 MCP 协议。 |
OPA_MCP_LOG_LEVEL | info | 可选值为 debug、info、warn、error。 |
OPA_MCP_MAX_RESPONSE_BYTES | 100000 | 单个工具响应的硬性上限。超出部分会被截断,并添加 __truncated: true 标记。小于 512 的值会被拒绝。 |
OPA_MCP_TIMEOUT_MS | 30000 | 对任何已启动子进程(opa、regal)设置的硬性超时时间。超时后,会先向子进程发送 SIGTERM,然后发送 SIGKILL。 |
OPA_MCP_HTTP_TIMEOUT_MS | 15000 | 对 OPA REST API 每次请求设置的超时时间,从尝试建立连接起,直到收到响应的最后一个字节为止;超时会报告为 TIMEOUT。 |
OPA_MCP_NO_TELEMETRY | (未设置) | 设置为 1 以禁用匿名启动 ping。该 ping 会发送服务版本、操作系统平台和随机安装 ID;安装 ID 存储在 ~/.orygn/opa-mcp/install-id 中;容器和 CI 作业则会改为发送 container 或 ci 标签。绝不会发送策略内容或文件路径。 |
OPA_MCP_MAX_SUBPROCESS_BYTES | 33554432(32 MiB) | 从子进程的 stdout 和 stderr 捕获的最大字节数,两者分别计数。超出上限时,流会被截断,子进程会停止,工具会返回 OUTPUT_TOO_LARGE。这与 OPA_MCP_MAX_RESPONSE_BYTES 不同;后者会在输出已载入内存后再截短回复。 |
OPA_MCP_PASSTHROUGH_ENV | (未设置) | 以逗号分隔的变量名列表,这些变量会传递给 opa、regal 和 conftest。其他所有变量都会被屏蔽。此处列出的任何变量都可被服务评估的任何策略通过 opa.runtime().env 读取,因此仅应传入在该环境中安全的值。 |
OPA_MCP_BLOCK_ENV | (未设置) | 以逗号分隔的变量名列表。即使这些变量在内置允许列表中,也会对 opa、regal 和 conftest 屏蔽。最后应用此设置,因此它也会覆盖 OPA_MCP_PASSTHROUGH_ENV。可用它屏蔽可能包含凭据的代理变量,但会失去代理支持。 |
OPA_MCP_ALLOWED_PATHS 中的路径必须是绝对路径,*_BINARY 的值则必须是通过 PATH 查找的命令名,或绝对路径;其他值都会导致服务在启动时停止。无法运行的二进制文件会在每次工具调用时通过结构化错误报告。 |
工具参考
每个工具都会返回一个 JSON 信封:
{ "ok": true, "data": { ... }, "warnings": [ ... ] }
{ "ok": false, "error": { "code": "INVALID_REGO", "message": "...", "hint": "...", "details": { ... } } }
稳定的错误代码: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。rego_eval 批处理还可能为某个条目返回 NOT_EVALUATED:如果某个输入超时导致调用停止,该条目即为尚未处理的输入。
类别 A:编写与静态分析
无需运行中的 OPA 服务即可对 Rego 源代码进行操作。封装 opa fmt、opa parse、opa check、opa inspect、opa capabilities、opa deps 和 regal。
| 工具 | 功能说明 |
|---|---|
rego_format | 格式化 Rego 源码。封装 opa fmt。具备幂等性。 |
rego_check | 对 Rego 进行类型检查和验证。封装 opa check。 |
rego_lint | 对文件或目录运行 Regal。返回每项违规的类别、级别和位置。需要将 regal 添加到 PATH,或设置 REGAL_BINARY。 |
rego_parse_ast | 将 Rego 解析为 AST JSON。封装 opa parse。 |
rego_inspect | 检查 bundle 或目录:包、规则和注释。封装 opa inspect。 |
rego_capabilities | 列出已解析的 opa 二进制文件支持的内置函数和功能(依次检查 OPA_BINARY、PATH 和捆绑副本);builtins 表示最多返回 100 个内置函数的完整记录 |
rego_deps | 静态依赖分析:规则级数据引用和跨包调用。 |
rego_migrate_v1 | 将 Rego v0 源码迁移到 v1。重命名 v1 保留名称的规则(contains、every、if、in),并将 v1 移除的内置函数替换为完全等效的函数,然后由 opa fmt --rego-v1 转换语法,再由 opa check 验证。给定 inputs 后,会将原始代码按 v0、迁移结果按 v1 分别对每个输入进行求值,并报告所有结果不同的规则,以及所有 queries(用于比较函数)。返回 { original, migrated, changed, valid, errors, rewrites, notes, equivalence }。dataPaths 用于加载策略在比较时读取的数据。 |
rego_check_schema | 根据 JSON Schema 检查 Rego。使用 opa check --schema 验证策略读取的每个 input.* 字段都存在于架构中。接受内联架构、JSON Schema 文件路径,或在策略声明了 schemas: 注释时接受架构目录。 |
精选: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
}
}
精选: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 }
}
]
}
}
类别 B:评估与测试
对策略和输入运行查询。封装 opa eval、opa test 和
opa bench。这些工具都接受 v0Compatible,以便在不迁移策略的情况下加载
OPA 1.0 之前编写的策略;其他通过 opa 或 conftest 读取策略的工具也都如此,
从 rego_check 到 rego_verify 和 conftest_test。然后,OPA 也会将查询作为 v0 读取,
因此会为其导入未来关键字,in 和 every 在其中仍可使用。rego_policy_diff 按侧接受该选项(v0CompatibleA、
v0CompatibleB),以便比较旧版策略及其迁移后的副本。例外是
rego_deps,因为 opa deps 没有此选项;以及 Regal 工具,它们不需要该选项,
因为 Regal 可以读取任一版本。
| 工具 | 功能 |
|---|---|
rego_eval | 针对策略和输入评估查询。这是最常用的工具。inputs 可在一次调用中针对最多 50 个输入文档评估查询,并逐一报告结果;如果没有策略,仅提供查询,则会尝试内置内容或表达式。每个结果都会说明查询是否为 defined,而 print() 的输出会显示在 printed 中。 |
rego_eval_with_explain | 使用 --explain=full 进行评估,并返回 OPA 的原始跟踪事件。rego_explain_decision 会将相同的跟踪呈现为易读的行。 |
rego_eval_with_profile | 使用 --profile 进行评估,并返回各规则的计时和评估次数。 |
rego_eval_with_coverage | 使用 --coverage 进行评估,并返回逐行覆盖率。 |
rego_test | 使用 opa test 运行 Rego 单元测试。返回通过、失败、跳过和错误的数量,以及每项测试的记录;errored 统计 OPA 无法评估的测试。除非有测试失败或出错,否则 coverage 或 threshold 也会添加覆盖率报告。只有至少运行了一项测试,且没有测试失败、出错或被跳过时,allPassed 才为 true。 |
rego_bench | 运行 opa bench 并返回统计计时数据。 |
rego_compile_query | 针对策略对查询进行部分评估。 |
opa_exec | 针对多个输入文件批量评估决策。返回各文件的结果,以及 successCount 和 errorCount。dataPaths 的加载方式与 opa eval --data 相同;bundle 接收一个 bundle。 |
rego_test_multiroot | 针对每个根目录运行一次 opa test 并汇总结果。当 opa test . 遇到包冲突时使用。汇总数据包含 totalErrored。 |
精选: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 } }] }]
}
}
类别 C:Bundle 操作
打包、签名并验证可部署的 Bundle。封装 opa build、opa sign 和 opa build --verification-key。
| 工具 | 功能 |
|---|---|
opa_bundle_build | 从策略目录构建 .tar.gz Bundle。支持 optimize 和 revision。 |
opa_bundle_sign | 使用私钥就地签名 Bundle 目录;不接受归档文件,因为 OPA 会从归档内部读取签名,而归档由 opa_bundle_build 签名。只要目录名称相同,目录签名在其放置位置不同时仍然有效。返回路径、算法和文件数。 |
opa_bundle_verify | 通过 opa build --verification-key 使用公钥验证已签名的 Bundle。失败时会说明原因:密钥错误、作用域错误、文件已修改、已添加、缺失或无法解析、未签名,或 Bundle 无法加载。 |
类别 D:OPA 服务管理
通过 REST API 与正在运行的 OPA 服务通信。要求 OPA_URL 指向可访问的服务。
| 工具 | 功能 |
|---|---|
opa_list_policies | 列出服务上注册的策略 ID,并显示数量。includeSource 和 includeAst 会分别添加 Rego 文本或解析后的 AST。 |
opa_get_policy | 按 ID 获取单个策略。返回 Rego 源代码;includeAst 会添加 OPA 解析后的 AST。 |
opa_put_policy | 上传或替换策略;replaced 表示此前是否存在该策略。无法编译的策略会返回 INVALID_REGO 及 OPA 的错误信息,且不会被存储。 |
opa_delete_policy | 按 ID 删除策略。 |
opa_get_data | 从数据层级中读取路径。 |
opa_put_data | 将数据写入数据层级中的路径。 |
opa_patch_data | 对数据层级应用 JSON Patch。 |
opa_delete_data | 从数据层级中删除文档。 |
opa_query_decision | 使用输入向 /v1/data/... 决策端点发送 POST 请求。defined: false 表示该路径未产生值,这与 false 不同。 |
opa_compile_query | 对照正在运行的服务对查询进行部分求值。 |
opa_health | 存活状态/就绪状态检查。若服务有响应,则会报告 healthy: true 或 healthy: false,并附上 OPA 给出的原因;OPA_UNREACHABLE 表示完全无法访问该服务。 |
opa_status | 与 opa_config 相同的 GET /v1/config 文档,位于 status 键下。不提供 Bundle 和决策日志状态(/v1/status)。服务头部值已脱敏。 |
opa_config | 来自 GET /v1/config 的服务配置。OPA 会移除 credentials 块,但会原样返回服务头部,因此此处会对头部值进行脱敏,并保留名称。 |
类别 E:更高层级的辅助工具
这是体现差异化的部分。它们将底层原语组合起来,以完成 Agent 实际需要执行的任务。
| 工具 | 功能说明 |
|---|---|
rego_explain_decision | 通过完整跟踪进行评估,并返回进入和触发的规则,以及以易读行形式呈现的跟踪信息。Fail 行会指出阻止规则的条件。 |
rego_generate_test_skeleton | 根据策略生成 _test.rego 骨架,每条规则对应一个存根。存根是 todo_test_ 规则,在填充并重命名为 test_ 之前,opa test 会将其报告为已跳过。 |
rego_describe_policy | 根据策略的 AST,总结其包、导入和各规则的结构。若要了解策略读取的输入引用,请使用 rego_infer_input_schema |
rego_suggest_fix | 原样传入 rego_check 返回的 errors 或 rego_lint 返回的 violations;该工具会为每条诊断返回一条修复建议及其置信度,并在有规则文档链接时一并返回。 |
rego_coverage_gaps | 运行 opa test --coverage,并按覆盖率最差的文件优先排序,返回各文件未覆盖的行范围。使用 threshold 筛选低于目标百分比的文件。 |
rego_security_audit | 在目录中运行仅限于 bugs 类别的 regal lint,并检查任何自定义 security 类别规则。返回按严重程度分组且附有修复指导的发现。无法解析的模块会列在 unparseable 中,其余模块则会接受审计。 |
rego_infer_input_schema | 使用 opa parse 对策略(或策略目录)进行静态分析,并返回描述策略读取的每个 input.* 字段的 JSON Schema。该工具会跟踪循环变量、规则和绑定到输入部分的函数参数,因此 some c in input.containers 后接 c.image 会得到 input.containers[].image。只有策略明确表明类型时才会设置类型。无需运行 OPA。可将其作为测试输入或 rego_check_schema schema 的起点;请先检查。 |
rego_fix | 运行 regal fix 自动应用机械式修复。Regal 0.42 及更高版本可修复 opa-fmt、use-rego-v1、use-assignment-operator、no-whitespace-comment、directory-package-mismatch、non-raw-regex-pattern、prefer-equals-comparison、redundant-existence-check 和 constant-condition;较旧版本只能修复其中一部分。使用 dryRun: true 可先预览更改。该工具会按文件列出应用了哪些规则;对于 directory-package-mismatch,还会返回文件移动到的新路径。 |
rego_format_write | 运行 opa fmt --write,就地规范格式化一个或多个 Rego 文件或目录。使用 dryRun: true 可列出将要更改的文件而不进行修改。写入前会验证所有文件均可成功解析。支持 regoV1、v0Compatible 和 v1Compatible 标志。只需要 opa。 |
rego_policy_diff | 并行对两个策略执行相同查询并比较结果。返回 equal: true/false、两侧的原始值(resultA/resultB)以及存在差异的 changedPaths(点号/方括号格式的 JSON 路径)。每一侧都可以使用内联源码或文件/目录路径。可用于验证重构前后的等价性,或了解两个策略版本之间的差异。inputs 会在一次调用中对最多 50 个输入文档分别进行比较,并返回 batch,其中每个输入对应一项;differing 表示结果不一致的输入数量。 |
rego_verify | 使用 SMT 求解(通过 WASM 调用 Microsoft Z3)对 Rego 规则的属性进行形式化验证。与测试不同,此工具会以数学方式检查所有可能的输入,并证明属性成立或返回具体反例。kind 字段接受 always_true、never_true 或 satisfiable。支持相等性、比较、字符串内置函数(startswith、endswith、contains、regex.match)、多子句规则、规则默认值、非布尔型规则头值和跨规则内联。对于失败即否定、推导式、部分集合和对象规则、函数、else 链及复杂正则表达式,会报告 INCONCLUSIVE,而不作猜测。读取不存在字段的主体表达式结果为 undefined,而非 true,因此 always_true 要求规则在空输入下也成立。 |
rego_explain_undefined | 解释 Rego 查询为何结果为 undefined、回退到默认值,或(对于 deny 等集合)不包含任何元素。该工具会结合普通求值、完整跟踪求值和逐条件 AST 分析,找出阻止各规则的确切主体表达式。返回结构化明细,指出阻止各规则的条件,并提供易读的摘要。 |
rego_playground_share | 将策略(以及可选的输入)发布为私密 GitHub Gist(传入 public: true 可将其设为公开),并返回链接,以便分享复现案例。需要具有 gist 范围的 GITHUB_TOKEN;否则返回 GITHUB_TOKEN_MISSING。 |
类别 F:Conftest(配置策略测试)
使用 conftest 根据 Rego 策略测试 Kubernetes 清单、Terraform 计划、Dockerfile、Helm chart,以及任何 YAML/JSON/HCL/TOML/INI 文件。需要在 PATH 中找到 conftest,或设置 CONFTEST_BINARY;否则,四种工具都会返回 CONFTEST_NOT_FOUND。
| 工具 | 功能 |
|---|---|
conftest_test | 使用 conftest test 根据 Rego 策略评估配置文件或内联文档。提供逐文件、逐命名空间的结果,数组始终存在,并按名称统计文件数。如果没有评估任何规则(命名空间错误,或没有 deny/violation/warn 规则),则报告 passed: false 和 nothingEvaluated: true,此时 conftest 本身的退出码为 0。 |
conftest_verify | 使用 conftest verify 运行 conftest 策略目录中的 test_* 规则。报告逐条规则的结果;如果没有规则,则返回 NO_TESTS_FOUND。 |
conftest_pull | 使用 conftest pull 从 OCI 注册表或 Git 仓库拉取策略包到本地目录。目标目录可以不存在;conftest 会创建该目录,并先清空目录,因此不要将其指向包含其他内容的目录。省略 policy 时会使用 conftest 默认值,该默认值本身必须位于允许的根目录中。 |
conftest_push | 使用 conftest push 将本地策略目录打包为 OCI 制品并推送到注册表。注册表凭据来自主机环境(docker login、ORAS 密钥链等)——不会通过工具传递凭据。 |
重点介绍:使用内联配置的 conftest_test
// 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
}
}
}
类别 G:元信息
| 工具 | 功能 |
|---|---|
mcp_server_info | 一次调用即可返回服务名称、版本、已解析的 opa/regal/conftest 版本、传输类型和 Node.js 版本。可用于确认 Agent 连接的是哪个服务实例。 |
提示词
服务器随附三个 MCP 提示词。 客户端会将它们显示为斜杠命令或工作流模板。
| 提示词 | 用途 |
|---|---|
policy_authoring_assistant | 引导 Agent 编写新策略:询问决策范围、起草、审查、格式化、检查并测试。 |
policy_review_checklist | 审查现有策略的检查清单:完整性、边缘情况、性能和安全隐患。 |
decision_debugging_workflow | 决策结果与预期不符时的诊断流程:收集输入、使用 explain 运行、隔离规则并提出修复方案。 |
资源
三个 MCP 资源 提供经过整理的参考数据,Agent 可随时读取。
| 资源 URI | 内容 |
|---|---|
opa://builtins | 分类整理的 OPA 内置函数参考,在读取时根据 opa capabilities --current 生成。会标记具有安全敏感性的函数(http.send、crypto.x509.*、opa.runtime)。 |
opa://style-guide | 精简的 Rego 风格指南,采用便于大模型处理的格式。 |
opa://patterns | 精选的常见模式库:RBAC、ABAC、Kubernetes 准入、IaC 门禁、API 授权和速率限制。每种模式都包含适用场景、完整的 Rego、一个测试和常见陷阱。 |
示例集
该工具集专为以下几种会话形式设计。
“帮我编写策略”
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>?
“为什么会被拒绝?”
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.
“将此策略推送到暂存环境中的 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.
架构
┌──────────────────────────────────── @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) │
└───────────────────────────────────────────────────────────────────────────────────────┘
如果要运行此服务,有四点值得了解:
- stdout 是协议通道。 服务通过
lib/logger.ts将日志写入文件,绝不会写入 stdout。如果看到多余的 stdout 字节,客户端就会断开连接;MCP 传输层非常严格。 - 工具处理程序不会抛出异常。 每个处理程序都会捕获自己的异常,并返回结构化的
{ ok: false, error: ... }封装,因此 Agent 看到的是稳定的错误词汇,而不是堆栈跟踪。未通过工具输入架构验证的参数不会到达处理程序:MCP 层会拒绝它,并返回isError: true的工具结果,其文本以MCP error -32602: Input validation error:开头,而不是返回该封装。子进程输出的解码发生在异步回调中,如果在其中抛出异常,就会绕过这些处理程序;因此,该路径会按字节数限制,而不是交给无法捕获它的try/catch处理。 - 子进程在时间、大小和环境方面都有上限。
lib/subprocess.ts使用shell: false运行二进制文件,并设置硬超时、先发送SIGTERM再升级为SIGKILL,同时限制每个流的字节数。服务中不存在 Agent 能构造 shell 命令的路径。仅有超时并不足够:opa会将结果缓冲在内存中,并在退出时一次性写入,因此,即使命令在远低于超时的时间内完成,也可能传输数百 MB。 - 子进程不会继承服务的环境变量。
lib/child-env.ts会改为构建一个明确的允许列表。Rego 可以通过opa.runtime().env读取其解释器的环境变量,因此,传递给子进程的任何内容都可被服务评估的任何策略读取,包括列表中的代理变量。
安全性
此服务设计为在用户自己的机器上,由 MCP 客户端启动并通过 stdio 通信,在本地运行。它并非为暴露到网络而设计。
- 基于文件的工具拒绝读取
OPA_MCP_ALLOWED_PATHS之外的任何内容。如果未设置该变量,文件工具会返回PATH_NOT_ALLOWED。 - 子进程以
shell: false运行,并设有硬超时和捕获输出的字节数上限。 - 经过评估的策略无法读取服务的环境变量。 Rego 通过
opa.runtime().env暴露opa进程的环境,因此,如果子进程继承了process.env,就会将OPA_TOKEN、GITHUB_TOKEN和所有其他变量交给它评估的任何策略。由于rego_eval接受内联源代码,无需访问文件系统即可触及这些变量,因此 Agent 读取的任何不可信 Rego 只需一次提示词注入,就能访问它们。子进程会获得明确的允许列表(lib/child-env.ts)。该列表不包含云服务或代码仓库令牌,但也并非不含凭据:HTTP_PROXY及其同类变量在列表中,而代理 URL 可能包含用户名和密码。保留这些变量是因为移除它们会影响所有使用企业代理的用户。即使如此,也可以在OPA_MCP_BLOCK_ENV中列出它们的名称,以将其排除。OPA_MCP_PASSTHROUGH_ENV可让个别变量重新加入。 OPA_TOKEN绝不会回显在工具响应或日志条目中,也不会传递给任何子进程。- 评估 Rego 的工具都标注为开放世界且非只读。
rego_eval及其变体、rego_test、rego_test_multiroot、rego_bench、rego_compile_query、opa_exec、rego_migrate_v1(提供inputs时)、explain、diff 和 coverage 辅助工具、conftest 工具,以及 Regal 工具(rego_lint、rego_security_audit、rego_fix,它们会运行项目的自定义规则)都会运行 Rego,而 OPA 的http.send允许策略访问并写入任何网络地址。根据提示信息执行门控的客户端会在运行其中一个工具前询问用户。opa_query_decision和opa_compile_query是例外:远程 OPA 会评估其已有的策略,这些工具的提示信息描述的是调用会对该服务执行什么操作。没有任何评估工具会传递或接受 capabilities 文件,因此无法限制评估时使用的http.send;rego_check和opa_bundle_build接受此类文件,但它只会影响检查和构建。 - 发布内容通过
npm provenance 发布;Docker 镜像基于已提交的
Dockerfile构建,其中opa和regal的版本已固定,并与其发布的摘要进行核对。
如需报告漏洞,请参阅 SECURITY.md。请勿公开发布安全问题。
故障排查
常见问题,快速解决。
OPA_BINARY_NOT_FOUND(或 REGAL_NOT_FOUND / CONFTEST_NOT_FOUND),即使二进制文件已安装也是如此。 (最常见的入门问题,请先阅读此项)
MCP 客户端(尤其是 Windows 和 macOS 上的 Claude Desktop)会使用经过刻意精简的 PATH 启动服务,其中不包含用户本地的 bin 目录,即使这些目录在交互式 Shell 中运行正常也不例外。二进制文件在你的计算机上,但启动的 MCP 服务无法看到它。
查找 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)
然后在客户端的 MCP env 块中,将 OPA_BINARY 设置为该绝对路径。其他二进制文件也适用同样的原因和解决方法:如果 rego_lint / rego_security_audit / rego_fix 报告 REGAL_NOT_FOUND,或 conftest_* 工具报告 CONFTEST_NOT_FOUND,请以同样的方式将 REGAL_BINARY / CONFTEST_BINARY 设置为对应的绝对路径(使用 which regal / which conftest 查找)。二进制文件位于 Shell 的 PATH 中还不够——启动的服务使用的是精简后的 PATH。examples/ 配置中已包含这些环境变量;只需修改占位路径即可。
此问题不会影响 Docker 安装方式,因为它会打包 opa 和 regal,完全绕过 PATH。MCPB 包会从 OPA_BINARY 或 PATH 中查找 opa,因此可能遇到此问题。
服务启动后,客户端提示“disconnected”。
最可能的原因是进程在 MCP 帧之外还向 stdout 写入了内容。如果你添加了自定义工具,请检查它调用的库是否会向 stdout 输出内容。固定位置的安全保障是 lib/logger.ts。请使用它,而不要使用 console.log。
项目中的文件触发 PATH_NOT_ALLOWED。
默认情况下,OPA_MCP_ALLOWED_PATHS 为空。请将你希望服务读取的绝对路径设置到该变量中,多个路径以逗号分隔。
调用 opa_* 工具时出现 OPA_UNREACHABLE。
OPA_URL(默认为 http://localhost:8181)必须指向正在运行的 OPA 服务(opa run --server ...)。使用 curl $OPA_URL/health 检查。
调用 opa_* 工具时出现 TIMEOUT。
请求未能在 OPA_MCP_HTTP_TIMEOUT_MS 指定的时间内完成(默认为 15 s)。可能是 OPA 已启动但响应缓慢,也可能是 OPA_URL 没有响应,且连接尝试被丢弃而非拒绝;从这里看两种情况并无区别。请检查 OPA_URL 和服务负载,或调高超时限制。
对内联源代码进行 lint 时出现 directory-package-mismatch 违规。
从 v0.1.1 起,服务会针对内联源代码调用自动禁用此规则。如果你仍看到该违规,说明正在运行较旧版本——请升级到 v0.1.1 或更高版本。要获取该规则的权威检查结果,请通过 paths 对磁盘上的实际文件执行 lint,而不要直接传入 source。
日志在哪里?
默认位置为 <OS-tmpdir>/orygn-opa-mcp.log。Linux/macOS 上通常是 /tmp/orygn-opa-mcp.log,Windows 上通常是 %TEMP%\orygn-opa-mcp.log。设置 OPA_MCP_LOG_FILE 可更改日志文件位置,设置 OPA_MCP_LOG_LEVEL=debug 可输出更详细的日志。
开发
git clone https://github.com/OrygnsCode/opa-mcp-server.git
cd opa-mcp-server
npm install
npm run dev
常用命令:
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 会在每次推送和 PR 时,在 Ubuntu 和 Windows 上使用 Node 22、24 和 26,并在 macOS 上使用 Node 22,运行 lint、类型检查、构建和单元测试。集成测试会在 Linux 上运行,并在 Windows 上作为非必需检查运行,使用固定版本的 opa、regal 和 conftest 发布版。
如需了解完整的贡献者工作流(添加工具、命名约定、日志规范、发布流程),请参阅 CONTRIBUTING.md。
版本管理与支持
本项目遵循 Semantic Versioning。对于语义化版本管理,公开接口包括已注册的工具、提示词和资源,其输入/输出架构、已识别的环境变量,以及 CLI 入口。
重大变更将:
- 在新的主版本下通过 CHANGELOG.md 公告,
- 至少提前一个次要版本发布弃用警告,
- 在发布公告中附上迁移说明。
上游工具链(opa 和 regal)的固定版本视为构建的一部分,而不是由运维人员管理的依赖项。Dockerfile 和 CI 使用相同的固定版本;升级通过 Dependabot 或手动 PR 进行。
许可证
@orygn/opa-mcp 是一个独立项目,与 Open Policy Agent 项目、Cloud Native Computing Foundation、Styra 或 Anthropic 均无关联,也未获其认可或赞助。“Open Policy Agent”和“Rego”是其各自所有者的商标。“Model Context Protocol”是 Anthropic, PBC 的商标。
已列入 OPA Ecosystem。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。