rails-mcp
The server provides governance and safety for AI agents with a default-deny action registry, an append-only spend-intent ledger, and a read-only sign-off audit trail. You can:
Classify actions:
classify_actionalways returnsGATED— an invariant that cannot be configured away — to use in your own interceptors or hooks as a safety rail.Check action registration:
is_action_registeredlets you query registered action types and their metadata (enforcement layer, pointer, ceremony); purely informational, no effect on the GATED verdict.Retrieve registry hash:
get_rails_hashreturns a 12-hex SHA-256 digest of the current action registry, which is what a human signs off against.Read human sign-off state:
get_signoff_stateshows the active sign-off (operator, timestamp, hash, note) or null. Signing itself is CLI-only to prevent agent self-approval.Record spend intents:
record_spend_intentappends immutable entries (amount, vendor, purpose, actor) to an append-only ledger. It never initiates or blocks real transactions.Evaluate budget:
evaluate_budgetsums spend intents within a rolling time window (default 30 days) and reports total spent and whether it's within a given limit. An empty ledger returnstotal_spent_usd=0.0, within_budget=True.
The server loads a user-specified YAML/JSON registry configuration, maintaining an audit trail for both spend and sign-offs.
rails-mcp
A self-hosted, caller-configured default-deny action registry + append-only spend ledger + CLI-only sign-off audit trail, exposed as MCP tools. Different category from this author's other six MCP servers (mcp-factory, rag-mcp, bus-mcp, desktop-mcp, github-mcp, discord-mcp) -- those are devtools ("connect an agent to X"); this one is governance and safety: "stop an agent from doing something irreversible without a human noticing."
Ported and generalized from a live internal registry (shared/rails/,
31 tests, running against a real multi-bot fleet since 2026-07-06) --
this pattern shipped internally before it shipped publicly.
What this is / is not
Is:
A schema + pure logic for classifying
action_typestrings as unconditionally GATED (default-deny), registered or not.A place to register what you know about an action-type's current enforcement (
enforcement_layer,enforcement_pointer,ceremony) -- informational, never permissive.An append-only spend-intent ledger + rolling-window budget check.
An append-only human sign-off ledger, recording who blessed the registry's current hash and when.
Is NOT:
Not an enforcer.
classify_actionreturningGATEDdoes not block anything by itself. You still wire it into your own PreToolUse hook, permission deny-list, or CI gate -- rails-mcp gives you the schema and the audit trail, not the interceptor.record_spend_intentrecords intent to spend; it never calls a vendor, a paid API, or a broker, and nothing here stops an over-budget spend from happening.Not pre-loaded with any action-type data. Every adopter supplies their own registry (a YAML/JSON config file, or a plain dict). No fleet's specific action-types ship with this package.
Not multi-tenant. The sign-off ledger assumes one human operator string per registry; fine for v1, a known limitation for later.
Related MCP server: AgentGuard MCP Server
The one invariant that is never configurable
classify_action(action_type) always returns "GATED" -- registered
or not, whatever config was loaded, no argument or config field can change
it. This is the whole product. A config-driven fail-open knob would defeat
the entire pitch, so classify() (rails_mcp/registry.py) takes only an
action_type argument: there is no parameter through which a caller could
ever make it return anything permissive. is_action_registered answers a
separate, purely informational question -- "do I know something about this
action-type's enforcement?" -- and never feeds back into the GATED verdict.
Quickstart (60 seconds)
pip install rails-mcpAdd to your Claude Desktop/Code MCP config:
{
"mcpServers": {
"rails-mcp": {
"command": "rails-mcp"
}
}
}No console script on PATH? Fall back to "command": "python", "args": ["-m", "rails_mcp"].
By default the registry loads empty (honest-empty, not fail-open --
classify_action is still unconditionally GATED for everything). Point
it at your own action-type config:
{
"mcpServers": {
"rails-mcp": {
"command": "rails-mcp",
"env": { "RAILS_MCP_CONFIG_PATH": "C:\\path\\to\\rails.config.yaml" }
}
}
}See examples/rails.config.example.yaml (or .example.json) for the
config shape.
Tools
All six are read-mostly -- none of them can write to the sign-off ledger.
Tool | Purpose |
| Default-deny verdict: always |
| Whether the loaded registry has an entry, plus |
| 12-hex sha256 digest of the loaded registry + entry count -- the value a human sign-off records. |
| Current active human sign-off, or |
| Append one spend-intent record. Never calls a vendor or paid API. |
| Rolling-window spend total vs. limit. Never raises. |
The CLI-only sign-off boundary -- and why it exists
append_signoff -- the function that records a human blessing the
registry's current hash -- is deliberately not an MCP tool, and never
will be. It is exposed only as a CLI command a human runs by hand:
rails-mcp sign --operator "jaime" --note "reviewed 2026-07-16 config"Why: the boundary exists to prevent an agent holding only this
server's MCP tool connection from self-approving an irreversible action.
If append_signoff were reachable as an MCP tool, any agent holding this
server's connection could sign its own registry -- silently defeating the
one thing the boundary exists to enforce. This mirrors the internal design
rule the original shared/rails/ implementation was built around: the
lane that builds the auditor never signs the registry it ships. An
auditor that can also sign isn't an auditor.
What this boundary does not prove: the sign-off ledger has no
cryptographic tamper-evidence and no binding to a real human identity --
its integrity rests entirely on filesystem ACLs and the self-hosted
deployment model, not on cryptography. An agent (or anyone) with shell or
file-write access to the ledger's path can run rails-mcp sign itself, or
hand-append a forged {"type": "signoff", ...} JSONL line straight into
the file -- the ledger has no way to tell that apart from a real CLI
invocation. The MCP-only boundary stops the narrower case of an agent that
has only this server's MCP tool connection; it is not proof that a human
reviewed anything, and shouldn't be read as one.
This boundary is enforced structurally, not just by convention:
rails_mcp/server.pyandrails_mcp/routes.pynever import or callappend_signoff, anywhere -- proven by an AST-based check (not a naive string grep, which would false-positive on this very explanation appearing in their docstrings) intests/test_server.py::test_append_signoff_unreachable_via_any_mcp_tool.The registered MCP tool set is exactly the 6 read-mostly tools above -- no
sign/append_signoff/revoke_signofftool exists, checked intests/test_server.py::test_all_six_rails_tools_registered.A behavioral test drives every registered tool and confirms the sign-off ledger file is never created (
test_no_registered_tool_can_create_a_signoff_record).run_server.py(the entrypoint~/.claude.jsoninvokes) imports onlyrails_mcp.server, neverrails_mcp.cli-- so even the process that serves MCP tools has no code path to thesignsubcommand.
Env vars
Var | Default | Purpose |
| unset | Path to your |
|
| Where the append-only sign-off ledger lives. |
|
| Where the append-only spend-intent ledger lives. |
Config file shape
actions:
deploy_prod:
enforcement_layer: "L1"
enforcement_pointer: "CI gate requires a passing e2e suite + a manual approve step"
ceremony: "operator hand"Or the more compact 3-element form (matches the internal registry's native shape):
actions:
deploy_prod: ["L1", "CI gate requires a passing e2e suite + a manual approve step", "operator hand"]JSON works identically ({"actions": {"deploy_prod": [...]}}). See
examples/ for full examples of both.
enforcement_layer should be honest, not aspirational -- "prose"
(no structural rail exists yet, just a doc) is a legitimate, correct value.
Rounding a "prose" entry up to "L1" because it feels better defeats the
entire point of an honest registry.
Testing
.venv/Scripts/python.exe -m pytest -qCI (.github/workflows/ci.yml) runs this suite on every push/PR and fails
the build if the Tests badge above drifts from what the suite actually
reports -- see scripts/check_readme_counts.py.
106 tests, all hermetic (every ledger/config path goes through tmp_path +
an autouse env-isolation fixture in tests/conftest.py; nothing touches a
real ./rails_data/). No network, no live-smoke gate needed -- this
server has no external API to fake.
tests/test_registry.py(24) -- the ported + generalized registry logic: default-deny property tests, immutability, hash determinism, sign-off ledger fold/append/load, structural no-shell-out proof.tests/test_spend_ledger.py(14) -- ported near-verbatim from the internal suite: append/load roundtrips, budget window math, naive- datetime honest-degrade, structural no-effector proof.tests/test_config.py(18) -- new: env-var resolution, YAML/JSON loading in both entry shapes, honest-empty-when-unconfigured, loud failure on an explicit missing path.tests/test_routes.py(14) -- the MCP tool surface's business logic, exercised directly.tests/test_server.py(17) -- tool registration, passthrough correctness, and the CLI-only sign-off structural + behavioral proof.tests/test_cli.py(8) -- theserve/signsubcommands, including thatsignis genuinely append-only and prints a human-readable confirmation.tests/test_check_readme_counts.py(11) -- this CI gate's own TDD suite: parse-claimed, parse-actual, compare, andmain()end-to-end against match/drift/missing fixtures.
Install / connect
python -m venv .venv
.venv/Scripts/python.exe -m pip install -e ".[test]"Registered in ~/.claude.json under mcpServers.rails-mcp as a stdio
server invoking run_server.py by absolute path (no cwd needed -- the
entrypoint adds its own directory to sys.path), OR via the rails-mcp
console script once installed from PyPI.
Handshake check
.venv/Scripts/python.exe scripts/list_tools.pyPrints the six registered tool names with no transport started.
Competitive picture (fact-checked 2026-07-16)
The closest prior art is not a hosted dead-man's-switch product -- that's a different problem ("is the operator still alive and watching"). The closer comparisons, once actually verified:
Microsoft Agent Governance Toolkit -- MIT-licensed, backed by Microsoft, broader/heavier policy-enforcement scope covering the OWASP Agentic Top 10. The "big-name, well-resourced" adjacent entrant.
Marchward -- the closest feature-for-feature match: server-side credential injection, spend caps, human-approval gates for irreversible actions, tamper-evident logging, Apache-2.0 open-source proxy.
AgentLedger -- AGPL-3.0, overlaps
spend_ledger.pyspecifically (budgets, approvals, audit trail).
rails-mcp's narrower bet: a small, inspectable, self-hosted
registry+ledger+audit-trail schema with one hard invariant (default-deny
classification can never be configured away) and one hard boundary
(sign-off is CLI-only, never MCP-reachable) -- not a full policy-engine
product.
Out of scope
Actual enforcement. No git hooks, no
settings.jsondeny rules, no graduation gates. You wireclassify_action/is_action_registeredinto your own interceptor.A coverage auditor that checks whether your specific enforcement mechanism (a hook, a CI gate) actually does what your registry claims. That is real, separate engineering (this author's internal
coverage_audit.py) and is not part of this package.Multi-tenant / multi-operator sign-off. One operator string per ledger for v1.
Blocking an over-budget spend.
evaluate_budgettells you the number; nothing here intercepts a call before it happens.Ledger rotation/capping.
record_spend_intentappends forever -- there's no rotation, size cap, or archival built in. A known limitation, not yet a problem at v1 scale.
Commercial support
Maintained by Jaimen Bell. For production MCP integrations, agent-governance rails, or agent-reliability work, see jaimenbell.dev.
Building your own MCP server? The MCP Starter Kit has templates, a build playbook, and packaging war-stories from shipping this one.
mcp-name: io.github.jaimenbell/rails-mcp
Available Tools
6 toolsclassify_actionA
Default-deny classification for an action_type: ALWAYS returns GATED, whether or not the action_type is registered. There is no fail-open branch and no argument that can change this -- it is the one invariant this server refuses to make configurable. Use is_action_registered to check whether an action_type has a known enforcement entry; that is a separate, informational question.
| Name | Required | Description | Default |
|---|---|---|---|
| action_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It fully discloses the invariant behavior: always returns GATED, no fail-open, no configurable argument. This is exceptionally transparent and removes any guesswork about the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the core behavior, and every sentence adds value without redundancy. It is appropriately concise for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is inherently simple, and the description covers behavior, usage, and alternatives. It addresses potential confusion about registration and provides a clear reference to the sibling tool. Nothing significant is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter action_type is implicitly explained as the identifier for the action. The description states that no argument can change the result, clarifying the parameter's role is nominal. This fully compensates for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool performs default-deny classification for an action_type and always returns GATED. It distinguishes itself from is_action_registered by explicitly noting that registration status does not affect the result.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: use this tool for enforcement classification (always GATED), and use is_action_registered for informational checks about registration. This effectively directs the agent to the appropriate sibling tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
evaluate_budgetA
Sum spend_intent amounts recorded within the last window_days and compare against limit_usd. Never raises -- an empty ledger reads as total_spent_usd=0.0, within_budget=True.
| Name | Required | Description | Default |
|---|---|---|---|
| limit_usd | Yes | ||
| window_days | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that the tool never raises exceptions and that an empty ledger yields total_spent_usd=0.0 and within_budget=True, which is valuable non-obvious behavior. However, it does not discuss other potential behaviors like rounding or timezone handling, so a 4 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no redundant words. The first sentence states the core operation, and the second adds a critical edge-case behavior. It is well-structured and front-loaded, earning a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with two parameters and an output schema. The description covers the operation and a key edge case. Since an output schema exists, it need not describe return values in detail. However, it lacks explicit usage context (when to use vs. alternatives), which is a minor gap. Thus a 4.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain parameters. It does explain that window_days is a time window and limit_usd is a comparison threshold, adding meaning beyond the bare schema. It does not specify units or constraints beyond what the schema already provides (e.g., default for window_days). Given the partial explanation, a 4 is suitable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Sum' and identifies the resources 'spend_intent amounts' and 'limit_usd', making the tool's function unambiguous. It clearly differs from sibling tools such as record_spend_intent (which records) and classify_action (which classifies), so it earns a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus alternatives, nor does it mention exclusions or prerequisites. It only implies usage for budget evaluation, so it receives a 3 for implied usage rather than explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_rails_hashA
12-hex sha256 digest of the currently loaded action registry, plus its entry count. Changes iff the registry's contents change -- this is the value a human sign-off (rails-mcp sign, CLI-only, never an MCP tool) records into the audit ledger.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, but the description discloses that the value changes iff the registry contents change and mentions the sign-off process is CLI-only. The read-only nature is implicit for a digest, and it adds meaningful context about the hash's role.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with no redundant text. The core output is front-loaded, followed by the change condition and sign-off context; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple no-parameter tool with an output schema, the description covers what it returns, when it changes, and why it matters. No gaps apparent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Tool has zero parameters and an empty schema, so baseline 4 applies. The description correctly omits parameter-specific details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the output: a 12-hex sha256 digest of the action registry plus entry count. Distinct from siblings like classify_action or evaluate_budget, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides context that the hash changes when registry contents change and that it is the value recorded in the audit ledger by human sign-off, note that sign-off is CLI-only and never an MCP tool. This implies when to use it, though it does not explicitly contrast with sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_signoff_stateA
Current active human sign-off of the registry (operator, signedAt, the registryHash they signed, optional note), or null if never signed or most-recently revoked. Read-only -- signing itself is a CLI-only ceremony (rails-mcp sign --operator ...), never something reachable from this or any MCP tool call.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does it well. It discloses the read-only nature, the null conditions (never signed or most-recently revoked), and that signing is inaccessible via MCP. This goes beyond basic operation to explain side effects and limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, front-loaded with the return value and states key edge cases and constraints. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists and no parameters, the description fully covers what an agent needs to know: what the tool returns, when it may return null, and that it cannot perform signing. It is complete for a zero-parameter read-only tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and 100% schema coverage (empty schema). Baseline for zero parameters is 4; the description adds meaningful context about the return value but correctly does not need to document parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: retrieves the current active human sign-off of the registry with specific fields (operator, signedAt, registryHash, optional note) or null. It is specific and distinct from sibling tools, all of which serve different purposes (classification, registration, hashing, spending, budgeting).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly notes this is a read-only operation and that signing is a CLI-only ceremony not reachable via any MCP tool. This provides a clear exclusion for when not to use it, though it does not explicitly name alternative tools for other sign-off-related tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_action_registeredA
Whether action_type has an entry in the loaded rails registry, plus its enforcement_layer / enforcement_pointer / ceremony when present. Registration is informational only -- classify_action's GATED verdict never depends on it.
| Name | Required | Description | Default |
|---|---|---|---|
| action_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It states the tool is informational only, implying a read-only, non-mutating operation. It also discloses that it returns enforcement_layer/enforcement_pointer/ceremony when present. However, it does not explicitly mention side effects or error behaviors, though for a simple lookup this is less critical.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary purpose. Every clause adds value: the first defines the query, the second clarifies its informational nature. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity and the presence of an output schema, the description is largely complete. It explains the relationship with classify_action and what data is returned. However, it does not define 'loaded rails registry' or specify edge cases, which would be helpful for full context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It only uses the parameter name 'action_type' in context without explaining valid values, format, or examples. The meaning is partially implied, but the description does not add sufficient semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: checking whether an action_type is registered in the rails registry. It specifies the exact resource (loaded rails registry) and the action (has an entry), and distinguishes itself from classify_action by clarifying that registration is informational only.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly mentions classify_action as an alternative and clarifies that this tool's results do not affect classification (GATED verdict). This tells the agent when to use this tool (for informational lookup) and when not to rely on it (not for gating decisions).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_spend_intentA
Append one spend-intent record to the append-only ledger. This RECORDS intent to spend -- it never calls a vendor, a paid API, or a broker, and it cannot itself authorize or block a spend.
| Name | Required | Description | Default |
|---|---|---|---|
| actor | Yes | ||
| vendor | Yes | ||
| purpose | Yes | ||
| amount_usd | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It transparently discloses that the ledger is append-only, that no external calls are made, and that the tool cannot authorize or block spend – all essential behavioral traits that go beyond the tool's name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, two sentences, with no filler. It front-loads the core action and then provides critical behavioral exclusions, making it easy to scan and understand quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers the main behavioral aspects and is supplemented by an output schema. However, the lack of parameter semantics and explicit usage guidance prevents it from being fully complete for a tool with 4 required parameters and no annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain any parameters. While 'amount_usd' and 'vendor' are self-explanatory, 'actor' and 'purpose' are ambiguous (e.g., who is the actor and what exactly is recorded in purpose). The description fails to compensate for the schema's lack of parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies the action ('Append one spend-intent record') and the resource ('append-only ledger'). It distinguishes this tool from its siblings by emphasizing that it only records intent and does not execute, authorize, or block spend – a unique purpose among the given sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when you need to log an intent to spend) but does not explicitly state when not to use it or name alternative tools. The phrase 'never calls a vendor... cannot authorize or block a spend' hints at boundaries but lacks direct guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
6 tool updates
v0.1.0- First observed
classify_action - First observed
evaluate_budget - First observed
get_rails_hash - First observed
get_signoff_state - First observed
is_action_registered - First observed
record_spend_intent
TDQS
Each tool targets a distinct operation: classification, registry lookup, hash digest, sign-off state, spend recording, and budget evaluation. Even the two action-related tools are explicitly differentiated: one always returns a fixed verdict, the other is purely informational.
All tool names follow a clear verb_noun pattern (classify_, is_, get_, record_, evaluate_). The 'is_' prefix for a boolean check is consistent with common naming conventions, and there is no mixing of styles.
Six tools is well within the ideal range for a focused governance/guardrail server. Each tool has a clear responsibility, and the set feels neither sparse nor bloated.
The surface covers the core lifecycle: classification, registry status, hash verification, sign-off state, spend intent recording, and budget evaluation. Minor gaps exist (e.g., no tool to inspect individual ledger entries or revoke sign-off), but these are intentionally delegated to CLI or aggregate operations, so the coverage is reasonable.
Maintenance
Related MCP Connectors
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
111Governance runtime for compliance: verified, human-approved writes to a tamper-evident record.
Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.
Fail-closed action authorization, MCP risk scanning, x402 checks, and signed receipts.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides MCP tools to enforce spend policies (allow, deny, step-up, allowlist) on agent wallets with an immutable audit trail.-
- FlicenseNot gradedqualityBmaintenanceProvides policy-driven runtime authorization and security evaluation for MCP-based agents, including MCP streaming HTTP gateway, mock MCP servers, deterministic agent demos, and audited tool invocation with redacted PostgreSQL audit chains.-
- AlicenseNot gradedqualityBmaintenanceMCP server that gates agent tool calls by normalizing intent, denying unknown/unattended destructive actions, and requiring HITL prove approval for high-risk operations. It maintains an append-only hash-chained Action Ledger and exposes gate_check and ledger_verify tools without ever executing tools.MIT
- AlicenseNot gradedqualityCmaintenanceEnforces deterministic security policies as an inline firewall for MCP server tool calls, with AST-based validation, cryptographic audit logging, and CLI-based evaluation and verification.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jaimenbell/rails-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server