mcpField
R
rails-mcp

rails-mcp

本地服务
github.com/jaimenbell安全011 周前更新

关于 rails-mcp

rails-mcp 是面向 Agent 治理与安全的可自托管 MCP 服务,提供动作登记、支出意图记录和人工签署审计。动作分类始终为 GATED;签署只能通过命令行完成,MCP 工具无法自行签署。

主要功能

  1. 01动作分类始终为 GATED
  2. 02登记动作执行信息
  3. 03追加式支出意图账本
  4. 04滚动窗口预算评估
  5. 05查询注册表哈希与签署状态
  6. 06命令行人工签署

适用场景

  1. 01在外部拦截器中检查动作分类
  2. 02记录并评估支出意图
  3. 03查看注册表对应的签署状态

MCP 相关

向 MCP 客户端提供六个只读为主的工具,用于动作分类、登记信息查询、预算评估及账本记录。人工签署仅通过命令行执行,不作为 MCP 工具提供。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"jaimenbell-rails": {
"command": "uvx",
"args": [
"rails-mcp"
]
}
}
}
启动命令uvx rails-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypirails-mcp0.1.0

工具

6

收录的工具列表 · 更新于 2 周前

参数类型必填说明
action_typestring是

详细介绍

rails-mcp

PyPI MCP Registry License: MIT Tests CI

一个可自托管、由调用方配置的默认拒绝操作注册表 + 仅追加的支出账本 + 仅限 CLI 的签核审计轨迹,以 MCP 工具的形式提供。与作者的另外六个 MCP 服务(mcp-factory、rag-mcp、bus-mcp、desktop-mcp、github-mcp、discord-mcp)属于不同类别——那些是开发工具(“将 Agent 连接到 X”);这个项目则关注治理与安全:“阻止 Agent 在无人察觉的情况下执行不可逆操作。”

它从一个正在运行的内部注册表(shared/rails/,31 个测试,自 2026-07-06 起在真实的多机器人群组中运行)移植并泛化而来——这种模式先在内部落地,然后才公开发布。

这是什么/不是什么

是:

  • 用于将 action_type 字符串分类为无条件受限(默认拒绝)的模式与纯逻辑,无论是否已注册。
  • 用于注册你所了解的操作类型当前执行机制(enforcement_layer、enforcement_pointer、ceremony)的信息库——仅供参考,绝不放行。
  • 仅追加的支出意向账本 + 滚动窗口预算检查。
  • 仅追加的人工签核账本,记录谁批准了注册表的当前哈希值以及时间。

不是:

  • 不是执行器。 classify_action 返回 GATED 本身并不会阻止任何操作。你仍需将其接入自己的 PreToolUse 钩子、权限拒绝列表或 CI 门禁——rails-mcp 提供模式和审计轨迹,而不是拦截器。record_spend_intent 记录支出意向;它绝不会调用供应商、付费 API 或经纪服务,这里也没有任何机制能阻止超预算支出。
  • 不预置任何操作类型数据。 每个采用者都需要提供自己的注册表(YAML/JSON 配置文件或普通 dict)。此软件包不包含任何群组的特定操作类型。
  • 不是多租户。 签核账本假定每个注册表只有一个人工操作者字符串;对 v1 来说足够,但已知后续版本仍需解决此限制。

永远不能配置的唯一不变量

classify_action(action_type) 始终返回 "GATED"——无论是否已注册、加载了什么配置,都没有任何参数或配置字段能够改变这一点。这就是整个产品。由配置驱动的故障时放行开关会使整个产品主张失去意义,因此 classify()(rails_mcp/registry.py)只接受 action_type 参数:没有任何参数可让调用方使其返回任何放行结果。is_action_registered 回答的是另一个纯粹提供信息的问题——“我是否了解此操作类型的执行机制?”——绝不会影响 GATED 判定。

快速入门(60 秒)

pip install rails-mcp

将以下内容添加到你的 Claude Desktop/Code MCP 配置中:

{
  "mcpServers": {
    "rails-mcp": {
      "command": "rails-mcp"
    }
  }
}

PATH 中没有控制台脚本?可以改用 "command": "python", "args": ["-m", "rails_mcp"]。

默认情况下,注册表加载时为空(如实为空,而非故障时放行——classify_action 对所有操作仍无条件返回 GATED)。将其指向你自己的操作类型配置:

{
  "mcpServers": {
    "rails-mcp": {
      "command": "rails-mcp",
      "env": { "RAILS_MCP_CONFIG_PATH": "C:\\path\\to\\rails.config.yaml" }
    }
  }
}

配置格式请参阅 examples/rails.config.example.yaml(或 .example.json)。

工具

这六个工具都以读取为主——没有一个能写入签署账本。

工具用途
classify_action(action_type)默认拒绝的判定:始终返回 "GATED"。实现在 rails_mcp/registry.py::classify 中,测试位于 tests/test_registry.py 和 tests/test_server.py。
is_action_registered(action_type)检查已加载的注册表中是否有对应条目,并在存在时返回 enforcement_layer/enforcement_pointer/ceremony。实现在 rails_mcp/routes.py::is_action_registered 中,测试位于 tests/test_routes.py。
get_rails_hash()已加载注册表的 12 位十六进制 sha256 摘要及条目数——这是人工签署时记录的值。实现在 rails_mcp/registry.py::rails_hash 中,测试位于 tests/test_registry.py。
get_signoff_state()当前有效的人工签署,或 null。只读。实现在 rails_mcp/registry.py::load_signoff_state 中,测试位于 tests/test_registry.py 和 tests/test_routes.py。
record_spend_intent(amount_usd, vendor, purpose, actor)追加一条支出意向记录。绝不会调用供应商或付费 API。实现在 rails_mcp/spend_ledger.py::record_spend_intent 中,测试位于 tests/test_spend_ledger.py。
evaluate_budget(limit_usd, window_days=30.0)滚动窗口内的支出总额与限额对比。绝不会抛出异常。实现在 rails_mcp/spend_ledger.py::evaluate_budget 中,测试位于 tests/test_spend_ledger.py。

仅限 CLI 的签署边界——以及它存在的原因

append_signoff——用于记录人工批准注册表当前哈希的函数——刻意不作为 MCP 工具提供,今后也不会提供。它仅作为 CLI 命令开放,供人工手动运行:

rails-mcp sign --operator "jaime" --note "reviewed 2026-07-16 config"

**原因:**此边界旨在防止仅持有此服务 MCP 工具连接的 Agent 自行批准不可逆操作。如果 append_signoff 可作为 MCP 工具调用,任何持有此服务连接的 Agent 都能签署自己的注册表——悄无声息地破坏此边界所要执行的唯一约束。这与原始 shared/rails/ 实现所遵循的内部设计规则一致:**构建审计器的通道,绝不签署其交付的注册表。**既能签署又能审计的,就不是审计器。

**此边界不能证明什么:**签署账本没有防篡改的密码学证据,也没有与真实人工身份绑定——其完整性完全依赖文件系统 ACL 和可自托管部署模式,而非密码学。拥有该账本路径的 shell 或文件写入权限的 Agent(或任何人)都能自行运行 rails-mcp sign,也能直接向文件中追加伪造的 {"type": "signoff", ...} JSONL 行——账本无法区分这种操作与真实的 CLI 调用。MCP 专属边界仅能阻止更狭窄的情况:某个 Agent 仅持有此服务的 MCP 工具连接;它不能证明有人进行了人工审查,也不应被理解为能证明这一点。

此边界通过结构实现,而不只是约定:

  • rails_mcp/server.py 和 rails_mcp/routes.py 在任何地方都不会导入或调用 append_signoff——这一点由基于 AST 的检查证明(而非简单的字符串 grep;后者会因这段说明出现在其文档字符串中而产生误报),检查位于 tests/test_server.py::test_append_signoff_unreachable_via_any_mcp_tool。
  • 已注册的 MCP 工具集恰好是上述 6 个以读取为主的工具——不存在 sign/append_signoff/revoke_signoff 工具,由 tests/test_server.py::test_all_six_rails_tools_registered 检查。
  • 一项行为测试会调用每个已注册工具,并确认绝不会创建签署账本文件(test_no_registered_tool_can_create_a_signoff_record)。
  • run_server.py(~/.claude.json 调用的入口点)只导入 rails_mcp.server,从不导入 rails_mcp.cli——因此,即使是提供 MCP 工具的进程,也没有通往 sign 子命令的代码路径。

环境变量

变量默认值用途
RAILS_MCP_CONFIG_PATH未设置rails.config.{yaml,yml,json} 的路径。未设置 = 空注册表(未注册任何内容,classify_action 仍无条件返回 GATED)。
RAILS_MCP_SIGNOFF_LEDGER_PATH./rails_data/signoff.jsonl仅追加式签署账本的存放位置。
RAILS_MCP_SPEND_LEDGER_PATH./rails_data/spend.jsonl仅追加式支出意图账本的存放位置。

配置文件格式

actions:
  deploy_prod:
    enforcement_layer: "L1"
    enforcement_pointer: "CI gate requires a passing e2e suite + a manual approve step"
    ceremony: "operator hand"

或者使用更精简的 3 元素格式(与内部注册表的原生格式一致):

actions:
  deploy_prod: ["L1", "CI gate requires a passing e2e suite + a manual approve step", "operator hand"]

JSON 的效果相同({"actions": {"deploy_prod": [...]}})。完整示例请参阅 examples/。

enforcement_layer 应当如实填写,而非一厢情愿——"prose" (尚无结构性护栏,只有文档)是合法且正确的值。 仅仅因为感觉更好,就把 "prose" 条目升为 "L1",会彻底违背如实登记的初衷。

测试

.venv/Scripts/python.exe -m pytest -q

CI(.github/workflows/ci.yml)会在每次推送 / PR 时运行此测试套件;如果上方 Tests 徽章与测试套件实际报告的结果不一致,就会导致构建失败——参见 scripts/check_readme_counts.py。

共 106 项测试,全部为隔离测试(所有账本 / 配置路径都通过 tmp_path + tests/conftest.py 中自动使用的环境隔离夹具处理;不会触及真实的 ./rails_data/)。无需网络,也无需实时冒烟测试门禁——此服务没有需要伪造的外部 API。

  • tests/test_registry.py(24 项)——移植并泛化的注册表逻辑: 默认拒绝属性测试、不可变性、哈希确定性、签署账本折叠 / 追加 / 加载、结构性无 shell 外调用证明。
  • tests/test_spend_ledger.py(14 项)——几乎原样移植自内部测试套件:追加 / 加载往返、预算窗口计算、对朴素 datetime 的如实降级、结构性无效应器证明。
  • tests/test_config.py(18 项)——新增:环境变量解析、两种入口格式的 YAML / JSON 加载、未配置时为空、显式指定路径不存在时明确报错。
  • tests/test_routes.py(14 项)——MCP 工具接口的业务逻辑,直接进行测试。
  • tests/test_server.py(17 项)——工具注册、透传正确性,以及仅限 CLI 的签署结构性与行为证明。
  • tests/test_cli.py(8 项)——serve / sign 子命令,包括验证 sign 确实仅追加,并会打印易读的确认信息。
  • tests/test_check_readme_counts.py(11 项)——此 CI 门禁自身的 TDD 测试套件:针对匹配 / 漂移 / 缺失夹具,端到端测试解析声明数量、解析实际数量、比较以及 main()。

安装 / 连接

python -m venv .venv
.venv/Scripts/python.exe -m pip install -e ".[test]"

在 ~/.claude.json 的 mcpServers.rails-mcp 下注册为 stdio 服务,通过绝对路径调用 run_server.py(无需 cwd——入口会将自身目录添加到 sys.path);或者从 PyPI 安装后使用 rails-mcp 控制台脚本。

握手检查

.venv/Scripts/python.exe scripts/list_tools.py

打印六个已注册工具的名称,不会启动传输。

竞争格局(已于 2026-07-16 核实)

最接近的既有方案不是托管式死亡开关产品——那解决的是另一个问题(“操作人员是否仍然存活并在监看”)。 实际核实后,更接近的对比如下:

  • Microsoft Agent Governance Toolkit ——采用 MIT 许可证,由 Microsoft 支持,政策执行范围更广、更全面,覆盖 OWASP Agentic Top 10。属于相邻领域中“知名度高、资源充足”的新参与者。
  • Marchward ——在功能上最为接近:服务端凭据注入、支出上限、针对不可逆操作的人类审批关卡、防篡改日志,以及采用 Apache-2.0 许可证的开源代理。
  • AgentLedger ——采用 AGPL-3.0 许可证,与 spend_ledger.py 有重叠之处(预算、审批、审计跟踪)。

rails-mcp 选择了更狭窄的方向:一个小巧、可检查、可自托管的注册表+账本+审计跟踪架构,具有一项不可妥协的不变量(默认拒绝分类绝不能被配置移除)和一项硬性边界(签核只能通过 CLI 进行,绝不允许通过 MCP 访问)——它不是一款完整的策略引擎产品。

不在范围内

  • 实际执行。 不提供 git hooks、settings.json 拒绝规则或晋级关卡。你需要将 classify_action/is_action_registered 接入自己的拦截器。
  • 覆盖审计器,用于检查你的特定执行机制(hook、CI 关卡)是否确实按注册表所述运行。这是独立且真实的工程工作(作者内部使用的 coverage_audit.py),不属于此软件包。
  • 多租户/多操作人员签核。 v1 中,每个账本只对应一个操作人员字符串。
  • 阻止超预算支出。 evaluate_budget 会告诉你金额;这里没有任何机制会在调用发生前拦截它。
  • 账本轮换/封顶。 record_spend_intent 会无限追加——内置功能不包括轮换、大小上限或归档。这是已知限制,但在 v1 的规模下尚未构成问题。

商业支持

由 Jaimen Bell 维护。有关生产环境 MCP 集成、Agent 治理护栏或 Agent 可靠性工作,请参阅 jaimenbell.dev。

正在构建自己的 MCP 服务?MCP Starter Kit 提供模板、构建指南,以及发布该服务过程中的经验教训。

mcp-name: io.github.jaimenbell/rails-mcp

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。