Skip to content

Inventory

From docs/MCP_TOOLS.md on GitHub

These tools answer "what do we have". find_assets and count_assets share one filter implementation (filter_assets in cloudg/mcp/catalog/_inventory.py).

find_assets

Category inventory · sensitivity confidential · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema yes · timeout: layer default (300 s)

Searches assets with any combination of filters, sorts, and pages through the result. Items are asset briefs; read an item's uri or call get_asset for detail.

Argument Type Default Constraints Description
query string "" Case-insensitive substring of name, ARN, id or a tag value.
provider string "" aws, azure or gcp.
asset_types string[] or null null AssetType values, e.g. ['EC2','S3_BUCKET'] (describe_schema).
region string "" Exact region, e.g. us-east-1.
account_id string "" Exact account / subscription / project.
tag string "" Tag filter: 'key' or 'key=value'.
internet_exposed boolean or null null Only exposed (true) / not exposed (false).
has_findings boolean or null null Only assets with (true) / without (false) open findings.
min_severity string "" Only assets with an open finding at or above this severity.
sort_by string "name" one of name, type, region, account, risk, findings 'risk' ranks by worst finding + exposure.
descending boolean false Reverse the order. For risk and findings the default is already highest first, so true puts the lowest first.
fields string[] or null null Project each item to these fields. Valid: id, name, type, provider, region, account_id, arn, internet_exposed, open_findings, max_severity, tags, uri
limit integer 50 1..500 Maximum items to return.
cursor string "" Opaque cursor from a previous call's next_cursor; empty = first page.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Filter semantics: query is a case-insensitive substring match against the name, ARN, id and every tag value. region matches exactly but ignores case; account_id matches exactly. tag is either a key that must be present or key=value with an exact value. has_findings and min_severity look at open findings only. All filters combine with AND. When the dataset has assets but none match, the result adds a hint pointing at list_asset_types, list_accounts and list_regions.

Internet-exposed EC2 instances with a HIGH or worse finding:

Called with the arguments below, find_assets returned this structuredContent.

{"asset_types": ["EC2"], "internet_exposed": true, "min_severity": "HIGH"}
{
  "dataset": "sample",
  "total": 1,
  "offset": 0,
  "returned": 1,
  "next_cursor": null,
  "truncated": false,
  "items": [
    {
      "id": "bastion",
      "name": "bastion",
      "type": "EC2",
      "provider": "AWS",
      "region": "us-east-1",
      "account_id": "111111111111",
      "arn": "arn:aws:ec2:us-east-1:111111111111:instance/i-0bast",
      "internet_exposed": true,
      "open_findings": 1,
      "max_severity": "HIGH",
      "uri": "cloudg://assets/bastion"
    }
  ]
}

Projection to name and tags for a tag filter:

Called with the arguments below, find_assets returned this structuredContent.

{"tag": "owner=web-team", "fields": ["name", "tags"]}
{
  "dataset": "sample",
  "total": 3,
  "offset": 0,
  "returned": 3,
  "next_cursor": null,
  "truncated": false,
  "items": [
    {
      "id": "web-1",
      "name": "web-1",
      "tags": {
        "env": "prod",
        "owner": "web-team"
      }
    },
    {
      "id": "web-2",
      "name": "web-2",
      "tags": {
        "env": "prod",
        "owner": "web-team"
      }
    },
    {
      "id": "alb-web",
      "name": "web-alb",
      "tags": {
        "env": "prod",
        "owner": "web-team"
      }
    }
  ]
}

No match:

Called with the arguments below, find_assets returned this structuredContent.

{"query": "kubernetes"}
{
  "dataset": "sample",
  "total": 0,
  "offset": 0,
  "returned": 0,
  "next_cursor": null,
  "truncated": false,
  "items": [],
  "hint": "No assets matched. Loosen the filters, or use list_asset_types / list_accounts / list_regions to see valid values."
}

Errors include unknown enum values, unknown fields, stale or invalid cursors (all shown under Conventions) and schema violations:

{
  "tool": "find_assets",
  "arguments": {
    "asset_types": [
      "LAMBDA"
    ]
  },
  "isError": true,
  "text": "Unknown asset type. Did you mean LAMBDA_FUNCTION, ALARM? Valid values: EC2, VIRTUAL_MACHINE, GCE_INSTANCE, LAMBDA_FUNCTION, CLOUD_FUNCTION, ECS_CLUSTER, EKS_CLU...",
  "_meta": {
    "cloudg/error_code": -32602,
    "cloudg/error_data": {
      "value": "LAMBDA",
      "valid": [
        "EC2",
        "VIRTUAL_MACHINE",
        "GCE_INSTANCE",
        "... 153 more"
      ],
      "close_matches": [
        "LAMBDA_FUNCTION",
        "ALARM"
      ]
    }
  }
}
{
  "tool": "find_assets",
  "arguments": {
    "limit": 1000
  },
  "isError": true,
  "text": "Invalid arguments: limit: Input should be less than or equal to 500",
  "_meta": {
    "cloudg/error_code": -32602,
    "cloudg/error_data": [
      {
        "loc": "limit",
        "msg": "Input should be less than or equal to 500",
        "type": "less_than_equal"
      }
    ]
  }
}

Related: count_assets for totals, get_asset for one asset, list_tags for valid tag values.

get_asset

Category inventory · sensitivity confidential · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema yes · timeout: layer default (300 s)

One asset in detail. Links cloudg://assets/{id} and cloudg://assets/{id}/neighbors.

Argument Type Default Constraints Description
ref string required min length 1 Asset reference: internal id, ARN / cloud resource id, unique name, or unique ARN tail (e.g. 'function:api' or 'i-0abc').
include_findings boolean true Include up to 25 open findings, highest risk first.
max_relations integer 20 0..200 How many edges to list in relations.sample (0 lists none; the counts are always complete).
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.
Field Meaning
asset brief fields, tags See Briefs.
dataset Dataset the asset came from.
service Cloud service derived from the ARN or type (ec2, lambda, iam...).
relations.outgoing, relations.incoming Edge counts by edge type, complete.
relations.sample The first max_relations edges (outgoing first) as edge briefs.
relations.total, relations.truncated Total edges and whether sample is cut.
dependencies.direct_depends_on, dependencies.direct_dependents One-hop counts from the dependency graph.
degree.in, degree.out Degree in the relationship graph (parallel edges count once).
findings Up to 25 open findings, highest risk first (omitted with include_findings: false).
metadata_keys Up to 100 metadata keys, sorted; fetch values with get_asset_metadata.
collected_at Collection timestamp or null.

Looked up by ARN tail i-0web1:

Called with the arguments below, get_asset returned this structuredContent.

{"ref": "i-0web1", "max_relations": 3}
{
  "id": "web-1",
  "name": "web-1",
  "type": "EC2",
  "provider": "AWS",
  "region": "us-east-1",
  "account_id": "111111111111",
  "arn": "arn:aws:ec2:us-east-1:111111111111:instance/i-0web1",
  "internet_exposed": false,
  "open_findings": 1,
  "max_severity": "HIGH",
  "uri": "cloudg://assets/web-1",
  "tags": {
    "env": "prod",
    "owner": "web-team"
  },
  "dataset": "sample",
  "service": "ec2",
  "relations": {
    "outgoing": {
      "ATTACHED_TO": 1,
      "ASSUMES_ROLE": 1
    },
    "incoming": {
      "CONTAINS": 1,
      "LOAD_BALANCER_TARGET": 1,
      "MONITORS": 1
    },
    "sample": [
      {
        "id": "e-web1-sg",
        "source": "web-1",
        "source_name": "web-1",
        "target": "sg-app",
        "target_name": "sg-app",
        "edge_type": "ATTACHED_TO",
        "relationship": null
      },
      {
        "id": "e-web1-role",
        "source": "web-1",
        "source_name": "web-1",
        "target": "app-role",
        "target_name": "app-role",
        "edge_type": "ASSUMES_ROLE",
        "relationship": null
      },
      {
        "id": "e-priv-web1",
        "source": "subnet-private",
        "source_name": "prod-private-a",
        "target": "web-1",
        "target_name": "web-1",
        "edge_type": "CONTAINS",
        "relationship": null
      }
    ],
    "total": 5,
    "truncated": true
  },
  "dependencies": {
    "direct_depends_on": 4,
    "direct_dependents": 1
  },
  "degree": {
    "in": 3,
    "out": 2
  },
  "findings": [
    {
      "id": "f-web-cve",
      "title": "CVE-2024-1234 in openssl 3.0.1",
      "severity": "HIGH",
      "risk_score": 7.8,
      "source_tool": "trivy",
      "resource_id": "web-1",
      "resource_arn": null,
      "asset_id": "web-1",
      "asset_name": "web-1",
      "compliance_frameworks": [
        "PCI-DSS"
      ],
      "is_suppressed": false,
      "cvss_score": 8.1,
      "detected_at": "2026-01-15T12:00:00+00:00",
      "uri": "cloudg://findings/f-web-cve"
    }
  ],
  "metadata_keys": [
    "imds_v2",
    "instance_type",
    "user_data"
  ],
  "collected_at": "2026-01-15T12:00:00+00:00"
}

The result also carried these resource links in content:

[
  {
    "type": "resource_link",
    "uri": "cloudg://assets/web-1",
    "name": "web-1",
    "title": "EC2 web-1",
    "mimeType": "application/json"
  },
  {
    "type": "resource_link",
    "uri": "cloudg://assets/web-1/neighbors",
    "name": "web-1 neighbors",
    "mimeType": "application/json"
  }
]

Related: get_asset_metadata, neighbors, findings_for_asset, blast_radius, the investigate_asset prompt.

get_asset_metadata

Category inventory · sensitivity restricted · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

The raw metadata the collector stored for an asset: configuration, policy documents, rules, declared relations. It can contain secrets, which is why the tool is restricted: strict and soc-analyst hide it, and standard redacts secret-looking values.

Argument Type Default Constraints Description
ref string required min length 1 Asset reference: internal id, ARN / cloud resource id, unique name, or unique ARN tail (e.g. 'function:api' or 'i-0abc').
keys string[] or null null Only these metadata keys (see get_asset.metadata_keys).
max_chars integer 40000 1000..200000 Size budget for the serialised metadata. Over budget, keys that would cross it are left out and truncated is true.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Returns id, name, type, metadata, truncated, and missing_keys when some requested keys do not exist. When the serialised metadata is longer than max_chars, keys are kept in their stored order while they fit and any key that would cross the budget is left out; truncated is then true, key_sizes lists the 50 largest keys with their serialised sizes, and hint asks for specific keys.

Called with the arguments below, get_asset_metadata returned this structuredContent.

{"ref": "web-1", "keys": ["instance_type", "imds_v2", "ami"]}
{
  "id": "web-1",
  "name": "web-1",
  "type": "EC2",
  "truncated": false,
  "metadata": {
    "instance_type": "t3.large",
    "imds_v2": false
  },
  "missing_keys": [
    "ami"
  ]
}

The same asset without keys, called through a layer with policy="standard". The user_data value is redacted and _meta reports the transform:

{
  "structured": {
    "id": "web-1",
    "name": "web-1",
    "type": "EC2",
    "truncated": false,
    "metadata": {
      "instance_type": "t3.large",
      "imds_v2": false,
      "user_data": "[REDACTED:sensitive_field]"
    }
  },
  "meta": {
    "cloudg/transforms": {
      "redacted": {
        "sensitive_field": 1
      },
      "content_annotations": {
        "audience": [
          "user"
        ],
        "priority": 0.75
      },
      "annotations": {
        "classification": {
          "sensitivity": "restricted",
          "withheld_entities": [
            "sensitive_field"
          ]
        },
        "provenance": {
          "kind": "tool",
          "name": "get_asset_metadata",
          "generated_at": "2026-10-09T14:25:17+00:00",
          "policy": "standard",
          "category": "inventory",
          "principal_roles": [
            "default",
            "local"
          ]
        },
        "transformed": {
          "redacted": 1
        }
      }
    },
    "cloudg/duration_ms": 0
  }
}

Related: get_asset (lists metadata_keys).

count_assets

Category inventory · sensitivity internal · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema yes · timeout: layer default (300 s)

Counts assets grouped by one dimension, with the same filters as find_assets (minus text, tag and finding filters). Returns only group keys and counts, so it is internal.

Argument Type Default Constraints Description
group_by string "type" one of type, provider, region, account, service, exposure, severity Grouping dimension. service is the cloud service parsed from the ARN or type, exposure is internet_exposed / internal, severity is the worst open finding (NONE when there is none).
provider string "" aws, azure or gcp (case-insensitive).
asset_types string[] or null null AssetType values to count.
region string "" Exact region (case-insensitive).
account_id string "" Exact account / subscription / project id.
internet_exposed boolean or null null Only exposed (true) or only not exposed (false).
top integer 50 1..500 Maximum number of groups returned (largest first).
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Returns dataset, group_by, total (assets that passed the filters), group_count, groups (largest first, at most top) and truncated.

Called with the arguments below, count_assets returned this structuredContent.

{"group_by": "provider"}
{
  "dataset": "sample",
  "group_by": "provider",
  "total": 44,
  "group_count": 3,
  "groups": {
    "AWS": 36,
    "AZURE": 5,
    "GCP": 3
  },
  "truncated": false
}

Called with the arguments below, count_assets returned this structuredContent.

{"group_by": "severity"}
{
  "dataset": "sample",
  "group_by": "severity",
  "total": 44,
  "group_count": 6,
  "groups": {
    "NONE": 34,
    "HIGH": 5,
    "CRITICAL": 2,
    "INFO": 1,
    "LOW": 1,
    "MEDIUM": 1
  },
  "truncated": false
}

Called with the arguments below, count_assets returned this structuredContent.

{"group_by": "service", "provider": "aws", "top": 5}
{
  "dataset": "sample",
  "group_by": "service",
  "total": 36,
  "group_count": 16,
  "groups": {
    "ec2": 10,
    "iam": 7,
    "organizations": 3,
    "s3": 3,
    "elasticloadbalancing": 2
  },
  "truncated": true
}

list_asset_types

Category inventory · sensitivity internal · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

The asset types present in the dataset with count, internet_exposed and open_findings per type, most common first. Pass these values to asset_types filters.

Argument Type Default Constraints Description
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Called with the arguments below, list_asset_types returned this structuredContent.

{}
{
  "dataset": "sample",
  "total_types": 31,
  "items": [
    {
      "type": "SECURITY_GROUP",
      "count": 4,
      "internet_exposed": 0,
      "open_findings": 1
    },
    {
      "type": "IAM_ROLE",
      "count": 4,
      "internet_exposed": 0,
      "open_findings": 1
    },
    {
      "type": "CLOUD_ACCOUNT",
      "count": 3,
      "internet_exposed": 0,
      "open_findings": 0
    },
    "... 28 more"
  ]
}

Related: describe_schema (every type cloudg knows), explain_asset_type.

list_accounts

Category inventory · sensitivity confidential · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

Accounts, subscriptions and projects seen on assets, most assets first. name comes from a CLOUD_ACCOUNT asset with the same account id; external is true when that asset's metadata marks it as outside the mapped estate (referenced, not collected). Assets without an account id are grouped under unknown. Default limit is 100.

Argument Type Default Constraints Description
limit integer 100 1..500 Maximum items to return.
cursor string "" Opaque cursor from a previous call's next_cursor; empty = first page.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Called with the arguments below, list_accounts returned this structuredContent.

{}
{
  "dataset": "sample",
  "total": 5,
  "offset": 0,
  "returned": 5,
  "next_cursor": null,
  "truncated": false,
  "items": [
    {
      "account_id": "111111111111",
      "provider": "AWS",
      "assets": 31,
      "regions": [
        "global",
        "us-east-1"
      ],
      "internet_exposed": 4,
      "open_findings": 7,
      "name": "prod",
      "external": false
    },
    {
      "account_id": "00000000-aaaa-bbbb-cccc-000000000001",
      "provider": "AZURE",
      "assets": 5,
      "regions": [
        "westeurope"
      ],
      "internet_exposed": 1,
      "open_findings": 1,
      "name": null,
      "external": false
    },
    "... 3 more"
  ]
}

Related: organization_topology, cross_account_edges.

list_regions

Category inventory · sensitivity internal · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

Regions found on assets with their providers, asset count and number of distinct accounts, plus scanned_regions, the regions each provider was configured or scanned for (empty for datasets loaded from a plain report).

Argument Type Default Constraints Description
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Called with the arguments below, list_regions returned this structuredContent.

{}
{
  "dataset": "sample",
  "total": 5,
  "items": [
    {
      "region": "us-east-1",
      "providers": [
        "AWS"
      ],
      "assets": 24,
      "accounts": 1
    },
    {
      "region": "global",
      "providers": [
        "AWS"
      ],
      "assets": 10,
      "accounts": 3
    },
    "... 3 more"
  ],
  "scanned_regions": {
    "aws": [
      "us-east-1",
      "eu-west-1"
    ],
    "azure": [
      "westeurope"
    ],
    "gcp": [
      "europe-west1"
    ]
  }
}

list_tags

Category inventory · sensitivity confidential · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

Tag keys with the number of assets carrying each, the number of distinct values and the most common values (5 per key, or up to top when key is given). Feed the result into find_assets(tag="key=value").

Argument Type Default Constraints Description
key string "" Only this tag key (shows its values).
top integer 30 1..200 Maximum number of tag keys returned. With key, also the number of values shown.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Called with the arguments below, list_tags returned this structuredContent.

{}
{
  "dataset": "sample",
  "total": 3,
  "returned": 3,
  "truncated": false,
  "items": [
    {
      "key": "env",
      "assets": 8,
      "distinct_values": 1,
      "top_values": {
        "prod": 8
      }
    },
    {
      "key": "owner",
      "assets": 7,
      "distinct_values": 4,
      "top_values": {
        "web-team": 3,
        "platform": 2,
        "api-team": 1,
        "it-ops": 1
      }
    },
    {
      "key": "data",
      "assets": 2,
      "distinct_values": 1,
      "top_values": {
        "pii": 2
      }
    }
  ]
}

Called with the arguments below, list_tags returned this structuredContent.

{"key": "owner"}
{
  "dataset": "sample",
  "total": 1,
  "returned": 1,
  "truncated": false,
  "items": [
    {
      "key": "owner",
      "assets": 7,
      "distinct_values": 4,
      "top_values": {
        "web-team": 3,
        "platform": 2,
        "api-team": 1,
        "it-ops": 1
      }
    }
  ]
}

coverage_report

Category inventory · sensitivity internal · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

Which collectors succeeded or failed per provider, account and region during collection, so gaps such as AccessDenied are visible before the map is trusted. Live collections carry coverage records, and so do inventory maps: cloudg map saves them in inventory-map.json. Each record has provider, region, account_id, total_services, successful, failed, coverage_pct and failures[] with service and error, and the tool adds totals. The sample inventory holds one record:

Argument Type Default Constraints Description
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Called with the arguments below, coverage_report returned this structuredContent.

{}
{
  "dataset": "sample",
  "records": [
    {
      "provider": "aws",
      "region": "us-east-1",
      "account_id": "111111111111",
      "total_services": 3,
      "successful": 2,
      "failed": 1,
      "coverage_pct": 66.7,
      "failures": [
        {
          "service": "rds",
          "error": "AccessDenied: rds:DescribeDBInstances"
        }
      ]
    }
  ],
  "total_services": 3,
  "successful": 2,
  "failed": 1,
  "coverage_pct": 66.7
}

A dataset without records, such as report loaded from a findings.json, gets a note instead:

Called with the arguments below, coverage_report returned this structuredContent.

{"dataset": "report"}
{
  "dataset": "report",
  "records": [],
  "note": "This dataset has no coverage records (they come from live collections via map_inventory / collect_assets, and from inventory maps saved with them)."
}

A dataset produced by map_inventory (stubbed engine, see How the examples were produced) has the same shape:

Called with the arguments below, coverage_report returned this structuredContent.

{"dataset": "live-aws"}
{
  "dataset": "live-aws",
  "records": [
    {
      "provider": "aws",
      "region": "us-east-1",
      "account_id": "111111111111",
      "total_services": 3,
      "successful": 2,
      "failed": 1,
      "coverage_pct": 66.7,
      "failures": [
        {
          "service": "rds",
          "error": "AccessDenied: rds:DescribeDBInstances"
        }
      ]
    }
  ],
  "total_services": 3,
  "successful": 2,
  "failed": 1,
  "coverage_pct": 66.7
}

unresolved_references

Category inventory · sensitivity confidential · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

Relations the linker could not resolve to a mapped asset, for example a role ARN in a service that was not collected. These are blind spots in the graph. Items are passed through as the mapper stored them.

Argument Type Default Constraints Description
limit integer 50 1..500 Maximum items to return.
cursor string "" Opaque cursor from a previous call's next_cursor; empty = first page.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Called with the arguments below, unresolved_references returned this structuredContent.

{}
{
  "dataset": "sample",
  "total": 1,
  "offset": 0,
  "returned": 1,
  "next_cursor": null,
  "truncated": false,
  "items": [
    {
      "source": "web-1",
      "source_type": "EC2",
      "target": "arn:aws:iam::111111111111:role/missing-role",
      "edge": "ASSUMES_ROLE"
    }
  ]
}

organization_topology

Category inventory · sensitivity confidential · capabilities read_state · readOnly true, destructive false, idempotent true, openWorld false · outputSchema no · timeout: layer default (300 s)

The organization hierarchy. When the dataset carries organization discovery data (AWS Organizations, Control Tower, Azure management groups, GCP folders), the result has source: "organization_discovery" with organization_id, management_account_id, feature_set, control_tower_enabled, governed_regions, shared_accounts, ous[] (id, name, path, parent_id), accounts[] (id, name, status, ou_path, parent_id, at most max_accounts), total_accounts, truncated and, with include_policies, policies[] (id, name, type, aws_managed, targets).

Argument Type Default Constraints Description
include_policies boolean false Add SCPs / org policies and their targets.
max_accounts integer 200 1..1000 Cap on the accounts (or hierarchy nodes) listed.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Called with the arguments below, organization_topology returned this structuredContent.

{"include_policies": true}
{
  "dataset": "sample",
  "source": "organization_discovery",
  "organization_id": "o-sample",
  "management_account_id": "111111111111",
  "feature_set": "ALL",
  "control_tower_enabled": true,
  "governed_regions": [
    "us-east-1",
    "eu-west-1"
  ],
  "shared_accounts": {},
  "ous": [
    {
      "id": "ou-work",
      "name": "Workloads",
      "path": [
        "Root",
        "Workloads"
      ],
      "parent_id": "r-root"
    }
  ],
  "accounts": [
    {
      "id": "111111111111",
      "name": "prod",
      "status": "ACTIVE",
      "ou_path": [
        "Root",
        "Workloads"
      ],
      "parent_id": "ou-work"
    },
    {
      "id": "222222222222",
      "name": "shared-services",
      "status": "ACTIVE",
      "ou_path": [
        "Root",
        "Workloads"
      ],
      "parent_id": "ou-work"
    }
  ],
  "total_accounts": 2,
  "truncated": false,
  "policies": [
    {
      "id": "p-1",
      "name": "deny-unapproved-regions",
      "type": "SERVICE_CONTROL_POLICY",
      "aws_managed": false,
      "targets": [
        "ou-work"
      ]
    }
  ]
}

Without discovery data it falls back to the organization, OU and account assets on the map (source: "map_assets"), with parents taken from CONTAINS edges and policies from ORG_POLICY assets and their GOVERNS edges. The report dataset was loaded from findings.json, which keeps assets but not the discovery block:

Called with the arguments below, organization_topology returned this structuredContent.

{"dataset": "report", "include_policies": true}
{
  "dataset": "report",
  "source": "map_assets",
  "nodes": [
    {
      "id": "org",
      "name": "sample-org",
      "type": "ORGANIZATION",
      "account_id": "111111111111",
      "parent_id": null,
      "external": false
    },
    {
      "id": "ou-workloads",
      "name": "Workloads",
      "type": "ORG_UNIT",
      "account_id": "111111111111",
      "parent_id": "org",
      "external": false
    },
    "... 3 more"
  ],
  "total": 5,
  "truncated": false,
  "policies": [
    {
      "id": "scp-deny-regions",
      "name": "deny-unapproved-regions",
      "targets": [
        "ou-workloads"
      ]
    }
  ]
}

With neither, it returns source: null and a note.

Related: list_accounts, cross_account_edges, the cross_account_trust_review prompt.