diff --git a/pkg/policy/criteria/mcp_tool.go b/pkg/policy/criteria/mcp_tool.go index a16f2bed7..db31634b3 100644 --- a/pkg/policy/criteria/mcp_tool.go +++ b/pkg/policy/criteria/mcp_tool.go @@ -23,29 +23,38 @@ func (c mcpToolCriterion) GenerateRule(_ string, data parser.Value) (*ast.Rule, r1 := c.g.NewRule(c.Name()) r1.Head.Value = NewCriterionTerm(true, ReasonMCPNotAToolCall) r1.Body = ast.Body{ - ast.MustParseExpr(`input.mcp.method != "tools/call"`), + ast.MustParseExpr(`not input.mcp.method`), } r2 := &ast.Rule{ + Head: generator.NewHead("", NewCriterionTerm(true, ReasonMCPNotAToolCall)), + Body: ast.Body{ + ast.MustParseExpr(`input.mcp.method`), + ast.MustParseExpr(`input.mcp.method != "tools/call"`), + }, + } + r1.Else = r2 + + r3 := &ast.Rule{ Head: generator.NewHead("", NewCriterionTerm(true, ReasonMCPToolOK)), Body: ast.Body{ ast.MustParseExpr(`input.mcp.method == "tools/call"`), }, } toolRef := ast.RefTerm(ast.VarTerm("input"), ast.VarTerm("mcp"), ast.VarTerm("tool_call"), ast.VarTerm("name")) - err := matchString(&r2.Body, toolRef, data) + err := matchString(&r3.Body, toolRef, data) if err != nil { return nil, nil, err } - r1.Else = r2 + r2.Else = r3 - r3 := &ast.Rule{ + r4 := &ast.Rule{ Head: generator.NewHead("", NewCriterionTerm(false, ReasonMCPToolUnauthorized)), Body: ast.Body{ ast.NewExpr(ast.BooleanTerm(true)), }, } - r2.Else = r3 + r3.Else = r4 return r1, nil, nil } diff --git a/pkg/policy/criteria/mcp_tool_test.go b/pkg/policy/criteria/mcp_tool_test.go index 365818332..d19fa9d4b 100644 --- a/pkg/policy/criteria/mcp_tool_test.go +++ b/pkg/policy/criteria/mcp_tool_test.go @@ -68,4 +68,15 @@ allow: require.Equal(t, A{true, A{ReasonMCPNotAToolCall}, M{}}, res["allow"]) require.Equal(t, A{false, A{}}, res["deny"]) }) + t.Run("no method name should pass", func(t *testing.T) { + res, err := evaluate(t, ` +allow: + and: + - mcp_tool: + is: list_tables +`, []*databroker.Record{}, Input{}) + require.NoError(t, err) + require.Equal(t, A{true, A{ReasonMCPNotAToolCall}, M{}}, res["allow"]) + require.Equal(t, A{false, A{}}, res["deny"]) + }) }