Repository navigation
feat(mcp): every refused query records the guard rule that refused it (#1231) - #1232
Merged
Merged
Conversation
…#1231) The guard returned only a message, so the activity log could say what a refused query said but not which rule caught it. Each refusal now has a stable rule id (read_only_only, single_statement, data_modifying, ...). The id travels with the tool error to the call record and into a new refusal_rule column of mcp_activity (schema v12; rows written before it read as no rule). The message the model reads does not change.
This was referenced Oct 9, 2026
Merged
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.
Refs #1231
What was wrong
McpSqlGuardreturned only a message for a refused query. The activity log kept that text, so a refusal could be read but not grouped by the rule that caught it.Changes
McpSqlGuard.refusalreturns aMcpSqlRefusalwith a stable rule id and the message. The nine refusals have ids:empty_query,single_statement,mysql_executable_comment,sqlite_pragma,read_only_only,function_not_allowed,explain_analyze_or_write,data_modifying,select_into_or_lock.checkreturns the same message as before.McpToolException.rule) to the call record and into the activity entry.mcp_activitygets arefusal_rulecolumn (schema v12). Existing databases get it through anALTER TABLE; rows written before it read as no rule.Not in this PR
Not verified locally
Tests were not run locally, per the project rule.