docs: say that the guard filters tools/list, not just calls - #5
Merged
Conversation
The README described the guard as a tool allowlist enforced at the wire, which undersells it. Denial happens twice and the first one matters more: tools/list is filtered to the allowlist before the client sees it, so a denied tool is never advertised to the model at all. The call-time block is the backstop. That behaviour was only documented in a bash comment in the verification snippet, so the front door never said it and the decision-tiers table read as if deny were purely a call-time check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The README described
gateway-proxy guardas a tool allowlist enforced at the wire. That undersells it.Denial happens twice, and the first one matters more.
tools/listis filtered to the allowlist before the client ever sees it, so a denied tool is never advertised to the model. It cannot attempt what it is not shown. The call-time block is the backstop for a client that asks for a tool it was not offered.Why it needed saying
The behaviour was real but only documented in a bash comment inside the verification snippet in
docs/mcp-guardrails.md. The front door never mentioned it, and the decision-tiers table read as thoughdenywere purely a call-time check.Confirmed against a real run: with
policies/coinbase.policy.jsonloaded,tools/listthrough the guard returns onlycoinbase_products_tickerandcoinbase_balance.coinbase_orders_createandcoinbase_transferdo not appear at all.Changes
README.md— one paragraph in "What makes it interesting", including the default-deny consequence: an unknown tool stays blocked until someone adds it rather than allowed until someone notices.docs/mcp-guardrails.md— makes the two-stage denial explicit under the decision-tiers table.Docs only. No code, no behaviour change.
🤖 Generated with Claude Code