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: summary for counts, breakdowns, and samples.

  • detail_level: simple for compact statement rows.

  • detail_level: full for 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: simple for common statement and principal lookups, or advanced for workload principal, tag, parsed-condition, and evidence-aware lookups.

  • filters: the searchable fields. statement_text and subject_text are raw text filters; principal is structured identity context.

  • detail_level: how much metadata to return. summary is safest for broad searches, simple returns compact rows, and full returns parsed metadata and evidence fields.

Common top-level output fields:

  • response_type: summary, simple, or full.

  • total_count: number of matching statements after all filters run.

  • returned_count: number of detailed rows returned.

  • truncated: whether matching rows were omitted because of limit.

  • 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 for simple or full detail 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"
    }
  ]
}

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-group statements.

  • Treat request.principal.type and request.principal.id as identity evidence.

  • Return residual conditions separately.

  • Return match_confidence: exact only 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.type plus request.principal.compartment.id as identity evidence.

  • Return resolved_compartments when the compartment OCID can be mapped to a loaded compartment name and path.

  • Return exact only when no non-identity condition atoms remain.

  • Return identity_match_with_residual when 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.

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 marked required.

  • 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, or unknown; this should stay conservative when residual conditions are not fully evaluated.

  • confidence: high-level confidence for the set result.

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 reload externally 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.