Drools — 18 Operations for AI Agents
Drools rules encode the business decisions enterprises can't afford to get wrong: pricing, eligibility, compliance. act101 surfaces each rule's structure directly, so agents locate the condition driving a decision without wading through the whole rulebase.
This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Drools code through the act MCP server. 18 operations available: 0 refactor, 18 query, 0 analysis. Each operation is callable from Claude Code, Cursor, Codex, OpenCode, or any MCP-compatible agent host. Click any operation for a stable anchor link suitable for citation.
Worked Drools examples
act101 reads a DRL file's package, import, global, declared type, function, rule, and query statements as top-level declarations, plus a rule's own LHS binding variables ($var). skeleton states an explicit kind for most of these — module for the package, import, variable for a global, type_alias for a declared type — but a rule and a query both fall back to function, the same kind reported for an actual function declaration; skeleton and symbols also disagree on the declared type's own kind: type_alias from one, class from the other, for the identical block. symbols drops the package and import declarations entirely and adds each declared type's own fields, a function's parameters, and a rule or query's own top-level pattern-binding variable. Each example below is the verbatim output of the command shown, run against the file shown. Query outputs are pretty-printed with the timing block omitted.
Read the ruleset's declarations as a skeleton
underwriting.drl scores loan applicants: a declared RiskScore type, an isHighRisk function, a rule that flags a high-risk LoanApplication, and a query that finds already-flagged scores.
$ act query skeleton underwriting.drl
Before
package com.acme.underwriting;
import com.acme.model.LoanApplication;
global org.slf4j.Logger logger;
declare RiskScore
applicantId : String
score : int
end
function boolean isHighRisk(int score) {
return score > 700;
}
rule "Flag high risk applicant"
when
$app : LoanApplication( $score : creditScore > 0 )
eval( isHighRisk($score) )
then
logger.info("High risk: " + $app.getApplicantId());
end
query "findHighRiskApplicants"
$r : RiskScore( score > 700 )
end
Output
{
"type": "Skeleton",
"declarations": [
{
"kind": "module",
"name": "com.acme.underwriting",
"range": {
"start": {
"file": "underwriting.drl",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "underwriting.drl",
"line": 1,
"column": 31,
"byte_offset": 30
}
},
"name_range": {
"start": {
"file": "underwriting.drl",
"line": 1,
"column": 9,
"byte_offset": 8
},
"end": {
"file": "underwriting.drl",
"line": 1,
"column": 30,
"byte_offset": 29
}
}
},
{
"kind": "import",
"name": "com.acme.model.LoanApplication",
"range": {
"start": {
"file": "underwriting.drl",
"line": 3,
"column": 1,
"byte_offset": 32
},
"end": {
"file": "underwriting.drl",
"line": 3,
"column": 39,
"byte_offset": 70
}
},
"name_range": {
"start": {
"file": "underwriting.drl",
"line": 3,
"column": 8,
"byte_offset": 39
},
"end": {
"file": "underwriting.drl",
"line": 3,
"column": 38,
"byte_offset": 69
}
}
},
{
"kind": "variable",
"name": "logger",
"range": {
"start": {
"file": "underwriting.drl",
"line": 5,
"column": 1,
"byte_offset": 72
},
"end": {
"file": "underwriting.drl",
"line": 5,
"column": 32,
"byte_offset": 103
}
},
"name_range": {
"start": {
"file": "underwriting.drl",
"line": 5,
"column": 25,
"byte_offset": 96
},
"end": {
"file": "underwriting.drl",
"line": 5,
"column": 31,
"byte_offset": 102
}
}
},
{
"kind": "type_alias",
"name": "RiskScore",
"range": {
"start": {
"file": "underwriting.drl",
"line": 7,
"column": 1,
"byte_offset": 105
},
"end": {
"file": "underwriting.drl",
"line": 10,
"column": 4,
"byte_offset": 167
}
},
"name_range": {
"start": {
"file": "underwriting.drl",
"line": 7,
"column": 9,
"byte_offset": 113
},
"end": {
"file": "underwriting.drl",
"line": 7,
"column": 18,
"byte_offset": 122
}
}
},
{
"kind": "function",
"name": "isHighRisk",
"range": {
"start": {
"file": "underwriting.drl",
"line": 12,
"column": 1,
"byte_offset": 169
},
"end": {
"file": "underwriting.drl",
"line": 14,
"column": 2,
"byte_offset": 235
}
},
"name_range": {
"start": {
"file": "underwriting.drl",
"line": 12,
"column": 18,
"byte_offset": 186
},
"end": {
"file": "underwriting.drl",
"line": 12,
"column": 28,
"byte_offset": 196
}
}
},
{
"kind": "function",
"name": "\"Flag high risk applicant\"",
"range": {
"start": {
"file": "underwriting.drl",
"line": 16,
"column": 1,
"byte_offset": 237
},
"end": {
"file": "underwriting.drl",
"line": 22,
"column": 4,
"byte_offset": 444
}
},
"name_range": {
"start": {
"file": "underwriting.drl",
"line": 16,
"column": 6,
"byte_offset": 242
},
"end": {
"file": "underwriting.drl",
"line": 16,
"column": 32,
"byte_offset": 268
}
}
},
{
"kind": "function",
"name": "\"findHighRiskApplicants\"",
"range": {
"start": {
"file": "underwriting.drl",
"line": 24,
"column": 1,
"byte_offset": 446
},
"end": {
"file": "underwriting.drl",
"line": 26,
"column": 4,
"byte_offset": 514
}
},
"name_range": {
"start": {
"file": "underwriting.drl",
"line": 24,
"column": 7,
"byte_offset": 452
},
"end": {
"file": "underwriting.drl",
"line": 24,
"column": 31,
"byte_offset": 476
}
}
}
]
}
The skeleton reports seven declarations: the package as module, the import as import, logger as variable, RiskScore as type_alias, and isHighRisk, the "Flag high risk applicant" rule, and the "findHighRiskApplicants" query all as function — a rule and a query are not distinguished from a real function by kind.
List the type's fields, the function's parameter, and each rule's top-level binding as symbols
RiskScore declares two fields, applicantId and score; the rule's top-level pattern binds $app to the matched LoanApplication, and the query's binds $r to the matched RiskScore.
$ act query symbols underwriting.drl
Before
package com.acme.underwriting;
import com.acme.model.LoanApplication;
global org.slf4j.Logger logger;
declare RiskScore
applicantId : String
score : int
end
function boolean isHighRisk(int score) {
return score > 700;
}
rule "Flag high risk applicant"
when
$app : LoanApplication( $score : creditScore > 0 )
eval( isHighRisk($score) )
then
logger.info("High risk: " + $app.getApplicantId());
end
query "findHighRiskApplicants"
$r : RiskScore( score > 700 )
end
Output
{
"type": "Symbols",
"symbols": [
{
"name": "logger",
"kind": "variable",
"range": {
"start": {
"file": "underwriting.drl",
"line": 5,
"column": 25,
"byte_offset": 96
},
"end": {
"file": "underwriting.drl",
"line": 5,
"column": 31,
"byte_offset": 102
}
},
"visibility": "unknown"
},
{
"name": "RiskScore",
"kind": "class",
"range": {
"start": {
"file": "underwriting.drl",
"line": 7,
"column": 9,
"byte_offset": 113
},
"end": {
"file": "underwriting.drl",
"line": 7,
"column": 18,
"byte_offset": 122
}
},
"visibility": "unknown"
},
{
"name": "applicantId",
"kind": "field",
"range": {
"start": {
"file": "underwriting.drl",
"line": 8,
"column": 5,
"byte_offset": 127
},
"end": {
"file": "underwriting.drl",
"line": 8,
"column": 16,
"byte_offset": 138
}
},
"visibility": "unknown"
},
{
"name": "score",
"kind": "field",
"range": {
"start": {
"file": "underwriting.drl",
"line": 9,
"column": 5,
"byte_offset": 152
},
"end": {
"file": "underwriting.drl",
"line": 9,
"column": 10,
"byte_offset": 157
}
},
"visibility": "unknown"
},
{
"name": "isHighRisk",
"kind": "function",
"range": {
"start": {
"file": "underwriting.drl",
"line": 12,
"column": 18,
"byte_offset": 186
},
"end": {
"file": "underwriting.drl",
"line": 12,
"column": 28,
"byte_offset": 196
}
},
"visibility": "unknown"
},
{
"name": "score",
"kind": "parameter",
"range": {
"start": {
"file": "underwriting.drl",
"line": 12,
"column": 33,
"byte_offset": 201
},
"end": {
"file": "underwriting.drl",
"line": 12,
"column": 38,
"byte_offset": 206
}
},
"visibility": "unknown"
},
{
"name": "\"Flag high risk applicant\"",
"kind": "function",
"range": {
"start": {
"file": "underwriting.drl",
"line": 16,
"column": 6,
"byte_offset": 242
},
"end": {
"file": "underwriting.drl",
"line": 16,
"column": 32,
"byte_offset": 268
}
},
"visibility": "unknown"
},
{
"name": "$app",
"kind": "variable",
"range": {
"start": {
"file": "underwriting.drl",
"line": 18,
"column": 9,
"byte_offset": 286
},
"end": {
"file": "underwriting.drl",
"line": 18,
"column": 13,
"byte_offset": 290
}
},
"visibility": "unknown"
},
{
"name": "\"findHighRiskApplicants\"",
"kind": "function",
"range": {
"start": {
"file": "underwriting.drl",
"line": 24,
"column": 7,
"byte_offset": 452
},
"end": {
"file": "underwriting.drl",
"line": 24,
"column": 31,
"byte_offset": 476
}
},
"visibility": "unknown"
},
{
"name": "$r",
"kind": "variable",
"range": {
"start": {
"file": "underwriting.drl",
"line": 25,
"column": 5,
"byte_offset": 481
},
"end": {
"file": "underwriting.drl",
"line": 25,
"column": 7,
"byte_offset": 483
}
},
"visibility": "unknown"
}
],
"parse_error": true
}
symbols drops the package and import, for ten entries, and adds applicantId/score as field, isHighRisk's own score parameter as parameter, and $app/$r as variable — but reports RiskScore as kind: class, disagreeing with the skeleton's type_alias for the identical declared-type block.
Query
18 query tools, the same on every supported language. Descriptions live in the shared reference: /docs/query-tools.
callers control_flow data_flow definition diagnostics effect_closure effect_summary fix_auto get_type graph import_organize interface mutations references repo_outline skeleton symbols symbols_batch