MCP and Policy Search Examples
This page shows example requests and expected response shapes for the compact MCP search surface. It starts with simple policy searches and builds toward workload principal analysis, search sets, identity lookup, data operations, and historical comparison.
The examples are intentionally verbose for documentation. MCP tool descriptions should stay terse.
Result Detail Levels
Most policy_search examples use:
detail_level: summaryfor counts, breakdowns, and samples.detail_level: simplefor compact statement rows.detail_level: fullfor parsed statement metadata, principal evidence, condition atoms, residual conditions, resolved compartments, and confidence details.
limit controls the maximum number of detailed statement rows returned. The server should evaluate all matches, but return summary output when match count exceeds the limit. MCP-facing calls should cap limit at 50 or lower to avoid large protocol payloads.
Each search has three conceptual inputs:
mode:simplefor common statement and principal lookups, oradvancedfor workload principal, tag, parsed-condition, and evidence-aware lookups.filters: the searchable fields.statement_textandsubject_textare raw text filters;principalis structured identity context.detail_level: how much metadata to return.summaryis safest for broad searches,simplereturns compact rows, andfullreturns parsed metadata and evidence fields.
Common top-level output fields:
response_type:summary,simple, orfull.total_count: number of matching statements after all filters run.returned_count: number of detailed rows returned.truncated: whether matching rows were omitted because oflimit.breakdowns: count buckets by policy, compartment, subject type, verb, resource, and confidence when available.warnings: caveats such as broad filters, unsupported fields, or result truncation.statements: detailed rows forsimpleorfulldetail levels.
Compact statement rows include fields such as policy_name, compartment_path, statement_text, subject_type, principal_summary, verb, resource, permission, location, effective_path, where_clause_text, and match_confidence.
Advanced rows add evidence fields such as normalized_principals, principal_keys, principal_evidence, where_clause, condition_atoms, dynamic_group_rule_evidence, residual_conditions, match_confidence_reason, and resolved_compartments.
Principal Keys and Structured Fields
Callers can provide either a canonical principal_key or structured fields. They should not provide both in the same principal filter unless the server explicitly validates they are equivalent.
Structured fields are preferred for AI agents and UI forms because the server can compute the canonical key and apply workload-principal matching rules. When the MCP server runs with --log-level INFO, each tool call logs full input and truncated output, which is useful for confirming the computed filter shape. WARNING and higher suppress tool payload logging.
Examples:
{
"principal": {
"principal_key": "group:Default/Administrators"
}
}
{
"principal": {
"principal_type": "resource-principal",
"resource_type": "containerinstance",
"compartment_ocid": "ocid1.compartment.oc1..app"
}
}
The second example computes:
resource-principal:containerinstance/compartment:ocid1.compartment.oc1..app
Compartment Lookup
Use identity_search when a policy or workload-principal condition gives you a compartment OCID and you need the human-readable name or path for follow-up searches.
Lookup by OCID:
{
"entity_types": ["compartment"],
"ocid": ["ocid1.compartment.oc1..app"],
"limit": 10
}
Lookup by name or path:
{
"entity_types": ["compartment"],
"name": ["app"],
"compartment_path": ["ROOT/Prod/App"],
"limit": 10
}
Expected output fields:
{
"operation": "search",
"total_count": 1,
"compartments": [
{
"name": "App",
"ocid": "ocid1.compartment.oc1..app",
"compartment_path": "ROOT/Prod/App",
"parent_ocid": "ocid1.compartment.oc1..prod"
}
]
}
Simple Statement Text Search
Use this when the user asks for policies containing specific text.
Input:
{
"mode": "simple",
"detail_level": "simple",
"filters": {
"statement_text": ["manage all-resources"],
"effective_path": ["ROOT/Prod"]
},
"limit": 25
}
Expected output:
{
"response_type": "simple",
"total_count": 2,
"statements": [
{
"policy_name": "ProdAdmins",
"compartment_path": "ROOT",
"statement_text": "allow group ProdAdmins to manage all-resources in compartment Prod",
"subject_type": "group",
"principal_summary": "group ProdAdmins",
"verb": "manage",
"resource": "all-resources",
"effective_path": "ROOT/Prod",
"where_clause_text": "",
"match_confidence": ""
}
]
}
Human Principal Search
Use structured principal when the caller means an identity, not raw subject text.
Input:
{
"mode": "simple",
"detail_level": "simple",
"filters": {
"principal": {
"principal_type": "group",
"domain_name": "Default",
"name": "Administrators"
},
"verb": ["manage"]
},
"limit": 50
}
Expected behavior:
Match
group Default/Administrators.Match equivalent
group-id:<ocid>statements when identity data supports the equivalence.Return summary output if more than
limitstatements match.
Service Principal Search
Use service principals when the OCI service itself is the subject.
Input:
{
"mode": "simple",
"detail_level": "simple",
"filters": {
"principal": {
"principal_type": "service",
"name": "cloudguard"
},
"verb": ["read", "use"],
"resource": ["instances", "instance-family"]
},
"limit": 25
}
Expected behavior:
Match statements such as
allow service cloudguard to read instances in tenancy.Keep service principal matching separate from
subject_textso agents do not confuse service names with policy text search.
Subject Text Search
Use subject_text when the caller wants raw subject matching.
Input:
{
"mode": "simple",
"detail_level": "summary",
"filters": {
"subject_text": ["any-user"],
"resource": ["repos"]
}
}
Expected behavior: text-oriented match over statement subjects. This does not prove resource principal identity by itself.
Resource Principal, Specific Resource
Use this for any-user / any-group statements constrained by request.principal.*.
Input:
{
"mode": "advanced",
"detail_level": "full",
"filters": {
"principal": {
"principal_type": "resource-principal",
"resource_type": "containerinstance",
"ocid": "ocid1.computecontainerinstance.oc1..example",
"match_mode": "auto"
}
},
"limit": 25
}
Expected behavior:
Derive principal key
resource-principal:containerinstance/ocid1.computecontainerinstance.oc1..example.Search
any-user/any-groupstatements.Treat
request.principal.typeandrequest.principal.idas identity evidence.Return residual conditions separately.
Return
match_confidence: exactonly when the condition evidence uniquely identifies the principal and no residual condition remains.
Expected output fields:
{
"where_clause": "all { request.principal.type = 'containerinstance', request.operation = 'PullImage' }",
"condition_atoms": [
{
"id": "c1",
"left": "request.principal.type",
"operator": "=",
"right": "containerinstance",
"evidence_kind": "resource_principal"
},
{
"id": "c2",
"left": "request.operation",
"operator": "=",
"right": "PullImage",
"evidence_kind": "condition"
}
],
"residual_conditions": [
{
"left": "request.operation",
"operator": "=",
"right": "PullImage"
}
],
"match_confidence": "identity_match_with_residual",
"match_confidence_reason": "Principal type matched, but one or more non-identity conditions remain."
}
Resource Principal, Compartment Scope
Input:
{
"mode": "advanced",
"detail_level": "full",
"filters": {
"principal": {
"principal_type": "resource-principal",
"resource_type": "containerinstance",
"compartment_ocid": "ocid1.compartment.oc1..app",
"match_mode": "condition"
}
}
}
Expected behavior:
Derive principal key
resource-principal:containerinstance/compartment:ocid1.compartment.oc1..app.Treat
request.principal.typeplusrequest.principal.compartment.idas identity evidence.Return
resolved_compartmentswhen the compartment OCID can be mapped to a loaded compartment name and path.Return
exactonly when no non-identity condition atoms remain.Return
identity_match_with_residualwhen the statement also includes operations, permissions, tags, time, network, or other conditions.
Expected output fields:
{
"principal_keys": [
"resource-principal:containerinstance/compartment:ocid1.compartment.oc1..app"
],
"principal_evidence": [
{
"source": "condition",
"field": "request.principal.compartment.id",
"value": "ocid1.compartment.oc1..app"
}
],
"resolved_compartments": [
{
"ocid": "ocid1.compartment.oc1..app",
"name": "App",
"compartment_path": "ROOT/Prod/App"
}
],
"match_confidence": "exact"
}
Instance Principal, Dynamic Group Rule
Input:
{
"mode": "advanced",
"detail_level": "full",
"filters": {
"principal": {
"principal_type": "instance-principal",
"resource_type": "instance",
"compartment_ocid": "ocid1.compartment.oc1..app",
"match_mode": "dynamic_group_rule"
}
}
}
Expected behavior:
Derive principal key
instance-principal:instance/compartment:ocid1.compartment.oc1..app.Search dynamic group rules for
instance.compartment.id.Search policies for matching dynamic group subjects.
Return dynamic group rule evidence and resolved compartments when possible.
Dynamic group display fields:
{
"dynamic_group_rule_evidence": [
{
"dynamic_group_name": "AppInstances",
"matching_rule": "instance.compartment.id = 'ocid1.compartment.oc1..app'",
"condition_atoms": [
{
"left": "instance.compartment.id",
"operator": "=",
"right": "ocid1.compartment.oc1..app",
"evidence_kind": "instance_principal"
}
]
}
],
"resolved_compartments": [
{
"ocid": "ocid1.compartment.oc1..app",
"name": "App",
"compartment_path": "ROOT/Prod/App"
}
]
}
Instance Principal, Specific Instance
Input:
{
"mode": "advanced",
"detail_level": "full",
"filters": {
"principal": {
"principal_type": "instance-principal",
"resource_type": "instance",
"ocid": "ocid1.instance.oc1..worker",
"compartment_ocid": "ocid1.compartment.oc1..app"
}
},
"limit": 25
}
Expected behavior:
Derive principal key
instance-principal:instance/ocid1.instance.oc1..worker.Search dynamic group rules for direct instance OCID evidence and compartment evidence.
Search policies where the matched dynamic groups are policy subjects.
Return dynamic group rule evidence separately from policy statement condition evidence.
Tag-Based Condition Search
Input:
{
"mode": "advanced",
"detail_level": "full",
"filters": {
"condition": {
"tag_scope": "request.principal.group",
"tag_namespace": "Operations",
"tag_key": "Environment",
"tag_value": "prod"
}
}
}
Expected behavior:
Reuse known tag-condition parsing where reliable.
Return parsed condition structure and condition atoms.
Do not require full recursive condition evaluation for initial matching.
Condition Display Fields
Policies should display condition analysis using condition-oriented names, even when the source OCI syntax uses where.
Output:
{
"where_clause": "all { request.principal.type = 'containerinstance', target.resource.tag.Operations.Environment = 'prod' }",
"condition_atoms": [
{
"id": "c1",
"left": "request.principal.type",
"operator": "=",
"right": "containerinstance",
"evidence_kind": "resource_principal"
},
{
"id": "c2",
"left": "target.resource.tag.Operations.Environment",
"operator": "=",
"right": "prod",
"evidence_kind": "tag_condition"
}
]
}
The first implementation should parse and display the structure without relying on full recursive evaluation for filtering.
Search Set: Service Installation Validation
Use a search set when a service/product requires multiple human and workload permissions.
Input:
{
"intent": "install_validation",
"product_or_service": "container image pull from OCIR",
"searches": [
{
"search_id": "human-admins",
"label": "Human admins can manage repos",
"required": true,
"query": {
"mode": "simple",
"detail_level": "summary",
"filters": {
"principal": {
"principal_type": "group",
"domain_name": "Default",
"name": "ContainerAdmins"
},
"resource": ["repos"],
"verb": ["manage"]
}
}
},
{
"search_id": "container-runtime",
"label": "Container instance resource principal can pull images",
"required": true,
"query": {
"mode": "advanced",
"detail_level": "full",
"filters": {
"principal": {
"principal_type": "resource-principal",
"resource_type": "containerinstance"
},
"resource": ["repos"]
}
}
}
],
"evaluation": {
"require_human_principal_coverage": true,
"require_workload_principal_coverage": true,
"min_confidence": "identity_match_with_residual"
}
}
set_summary output:
{
"set_summary": {
"intent": "install_validation",
"product_or_service": "container image pull from OCIR",
"total_searches": 2,
"required_searches": 2,
"matched_required_searches": 1,
"missing_required_searches": ["container-runtime"],
"human_principal_coverage": "present",
"workload_principal_coverage": "ambiguous",
"service_principal_coverage": "not_requested",
"tag_condition_coverage": "not_requested",
"missing_or_ambiguous_items": [
{
"search_id": "container-runtime",
"reason": "Matched resource-principal type, but residual request.operation condition was not evaluated."
}
],
"likely_ready": "unknown",
"confidence": "medium"
}
}
set_summary fields:
total_searches: count of searches in the set.required_searches: count of searches markedrequired.matched_required_searches: required searches with acceptable matches.missing_required_searches: required search IDs with no acceptable match.human_principal_coverage: whether user/group requirements appear present.workload_principal_coverage: whether resource or instance principal requirements appear present.service_principal_coverage: whether service principal requirements appear present.missing_or_ambiguous_items: actionable gaps for humans and AI agents.likely_ready:yes,no, orunknown; this should stay conservative when residual conditions are not fully evaluated.confidence: high-level confidence for the set result.
History Search
Use history search to run the same search or search set against two snapshots.
Input:
{
"query_type": "set",
"query": {
"intent": "install_validation",
"product_or_service": "container image pull from OCIR",
"searches": [
{
"search_id": "container-runtime",
"label": "Container instance resource principal can pull images",
"required": true,
"query": {
"mode": "advanced",
"detail_level": "simple",
"filters": {
"principal": {
"principal_type": "resource-principal",
"resource_type": "containerinstance"
},
"resource": ["repos"]
}
}
}
]
},
"left": {
"source": "as_of",
"as_of": "2026-05-15T00:00:00Z"
},
"right": {
"source": "current"
},
"diff_mode": "statement_identity"
}
Expected output:
{
"left_count": 11,
"right_count": 12,
"added_count": 1,
"removed_count": 0,
"modified_count": 0,
"unchanged_count": 11,
"added_statements": [
{
"policy_name": "OCIRContainerRuntimeAccess",
"statement_text": "allow any-user to read repos in tenancy where request.principal.type = 'containerinstance'"
}
],
"left_snapshot_metadata": {
"source": "cache",
"cache_name": "tenancy_2026-05-14-23-45-00-UTC",
"confidence": "high"
},
"right_snapshot_metadata": {
"source": "current"
}
}
Data Operations
List available caches:
{
"operation": "list_caches",
"tenancy_name": "andgre5678"
}
Reload data and persist a fresh cache:
{
"operation": "reload"
}
Expected reload output includes status, counts, data_as_of, and the cache name when a new cache is saved.
Reliable cache creation options:
Restart the desktop, web, or MCP process on a scheduled interval.
Call MCP
reloadexternally from a scheduler.Use a future reload policy setting at application startup or MCP server startup.
Automatic reload policies are a roadmap item. History search should report the cache selected for as_of and the confidence that it represents the requested time.
MCP Call Logging
Start the MCP server with INFO logging when testing clients or validating generated filters:
python -m oci_policy_analysis.mcp_server --use-cache andgre5678_2026-06-15-12-00-00-UTC --transport streamable-http --log-level INFO
At INFO level, the server logs each tool call with full input and truncated output:
MCP call policy_search input(full)={...}
MCP call policy_search output(truncated)={...}
The output payload is capped for log readability. Use --log-level WARNING when you want normal operation without tool payload logging.