Skip to content

Resources and resource templates

From docs/MCP_TOOLS.md on GitHub

Resources are addressable, read-only views of the workspace. Tool results link to them instead of inlining large payloads, and clients can subscribe to them (see Progress and change notifications). They always read the active dataset. A static URI wins over a template; among templates the longest one that matches wins, so cloudg://findings/severity/HIGH is never read as a finding id. {var} stops at /, {+ref} may contain /, and values are percent-decoded before use, so cloudg://assets/arn%3Aaws%3As3%3A%3A%3Aprod-data and cloudg://assets/arn:aws:ec2:us-east-1:111111111111:instance/i-0bast both work.

Unlike tools, a failed read raises a JSON-RPC error (-32602 for an unknown URI, asset, finding, dataset, format or topic) instead of returning an error result.

URI MIME Sensitivity Returns Completions
cloudg://workspace application/json internal Workspace.status(), the workspace_status result without next_steps.
cloudg://datasets application/json internal active_dataset and the datasets listing.
cloudg://datasets/{dataset}/summary application/json internal The dataset_summary object of one dataset. dataset
cloudg://assets/{+ref} application/json confidential Asset brief with tags, relation counts by edge type, up to 10 open findings, metadata_keys, dependency counts. For a graph placeholder: id, external, name, degree. ref
cloudg://assets/{+ref}/neighbors application/json confidential asset (id), edges (up to 500 edge briefs), neighbors (briefs, or {id, external}). ref
cloudg://assets/{+ref}/findings application/json confidential asset brief and every open finding, highest risk first. ref
cloudg://findings/summary application/json internal Open and suppressed counts, severity_breakdown, by_tool.
cloudg://findings/{finding_id} application/json confidential Finding brief plus description, evidence, remediation. finding_id
cloudg://findings/severity/{severity} application/json confidential The first 200 open findings of one severity by risk, with total and truncated. severity
cloudg://compliance application/json internal compliance_summary for every framework.
cloudg://compliance/{framework} application/json internal posture rows (exact name match preferred, else substring) and up to 300 failing_controls. framework
cloudg://graph/d3 application/json confidential The whole relationship graph as D3 {nodes, links}.
cloudg://graph/{format} application/json for d3 and cytoscape, application/graphml+xml for graphml (the template lists application/json) restricted d3, cytoscape or graphml. Restricted because the GraphML form is one opaque string; use cloudg://graph/d3 under a confidential ceiling. format
cloudg://ontology/turtle text/turtle restricted The ontology in Turtle.
cloudg://ontology/{format} the format's own type (the template lists text/turtle) restricted turtle, json-ld (application/ld+json), xml (application/rdf+xml), nt (application/n-triples). format
cloudg://schema/asset-types application/json public Asset types by family.
cloudg://schema/asset-types/{asset_type} application/json public asset_type, family, note, ontology_class, terraform_type. asset_type
cloudg://schema/edge-types application/json public Each edge type with reads_as, typical and dependency_direction.
cloudg://schema/relation-types application/json public Relation types by relation group.
cloudg://docs application/json public available (whether the docs directory was found) and the topic list.
cloudg://docs/{topic} text/markdown public One documentation section (up to 40,000 characters). topic
cloudg://policy application/json internal Policy.describe(): profiles, rules, transforms, rate limits, vault statistics, never the vault key.
cloudg://privacy/detectors application/json public The list_detectors table for the caller.
cloudg://ratelimit application/json internal The rate_limit_status object.

A resource template can list only one MIME type, so for the two {format} templates the mimeType on the read result is the one to trust. Reading an ontology resource builds the ontology if needed but sends no progress notification.

cloudg://docs/{topic} cuts sections out of docs/DOCUMENTATION.md and docs/INVENTORY_REFERENCE.md by heading. Topics: mcp (a built-in usage guide), pipeline, cli, inputs, outputs, data-models, configuration, python-api, recipes, authentication, identifiers, edges, edge-types, relations, inventory-summary, dependencies, inventory-map, organization. The docs directory is $CLOUDG_DOCS_DIR or the docs/ folder next to the installed package; when neither exists, every topic except mcp returns a short note pointing at the online documentation.

The examples below were read from a fresh workspace holding sample, its snapshot baseline and after, with sample active.

cloudg://datasets/sample/summary returns the dataset_summary object shown earlier. One asset, addressed by its ARN:

cloudg://assets/arn:aws:ec2:us-east-1:111111111111:instance/i-0bast returned one application/json content item (1159 characters).

{
  "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",
  "tags": {
    "env": "prod",
    "owner": "platform"
  },
  "relations": {
    "outgoing": {
      "ATTACHED_TO": 1,
      "ASSUMES_ROLE": 1
    },
    "incoming": {
      "CONTAINS": 1
    }
  },
  "findings": [
    {
      "id": "f-bastion-imds",
      "title": "EC2 instance allows IMDSv1",
      "severity": "HIGH",
      "risk_score": 7.5,
      "source_tool": "prowler",
      "resource_id": "bastion",
      "resource_arn": null,
      "asset_id": "bastion",
      "asset_name": "bastion",
      "compliance_frameworks": [
        "CIS-AWS"
      ],
      "is_suppressed": false,
      "cvss_score": null,
      "detected_at": "2026-01-15T12:00:00+00:00",
      "uri": "cloudg://findings/f-bastion-imds"
    }
  ],
  "metadata_keys": [
    "public_ip"
  ],
  "dependencies": {
    "direct_depends_on": 3,
    "direct_dependents": 0
  }
}

Its neighbours, for the internet placeholder node:

cloudg://assets/0.0.0.0%2F0/neighbors returned one application/json content item (5180 characters).

{
  "asset": "0.0.0.0/0",
  "edges": [
    {
      "id": "e-inet-sgweb",
      "source": "0.0.0.0/0",
      "source_name": "0.0.0.0/0",
      "target": "sg-web",
      "target_name": "sg-web",
      "edge_type": "SECURITY_GROUP_RULE",
      "relationship": null,
      "port_range": "80,443",
      "protocol": "TCP",
      "cidr": "0.0.0.0/0",
      "ports": [
        443,
        80
      ],
      "direction": "ingress"
    },
    {
      "id": "e-inet-sgadmin",
      "source": "0.0.0.0/0",
      "source_name": "0.0.0.0/0",
      "target": "sg-admin",
      "target_name": "sg-admin",
      "edge_type": "SECURITY_GROUP_RULE",
      "relationship": null,
      "port_range": "22",
      "protocol": "TCP",
      "cidr": "0.0.0.0/0",
      "ports": [
        22
      ],
      "direction": "ingress"
    },
    "... 4 more"
  ],
  "neighbors": [
    {
      "id": "sg-web",
      "name": "sg-web",
      "type": "SECURITY_GROUP",
      "provider": "AWS",
      "region": "us-east-1",
      "account_id": "111111111111",
      "arn": "arn:aws:ec2:us-east-1:111111111111:security-group/sg-0web",
      "internet_exposed": false,
      "open_findings": 0,
      "max_severity": null,
      "uri": "cloudg://assets/sg-web"
    },
    {
      "id": "sg-admin",
      "name": "sg-admin",
      "type": "SECURITY_GROUP",
      "provider": "AWS",
      "region": "us-east-1",
      "account_id": "111111111111",
      "arn": "arn:aws:ec2:us-east-1:111111111111:security-group/sg-0admin",
      "internet_exposed": false,
      "open_findings": 1,
      "max_severity": "CRITICAL",
      "uri": "cloudg://assets/sg-admin"
    },
    "... 4 more"
  ]
}

cloudg://assets/sg-admin/findings returned one application/json content item (998 characters).

{
  "asset": {
    "id": "sg-admin",
    "name": "sg-admin",
    "type": "SECURITY_GROUP",
    "provider": "AWS",
    "region": "us-east-1",
    "account_id": "111111111111",
    "arn": "arn:aws:ec2:us-east-1:111111111111:security-group/sg-0admin",
    "internet_exposed": false,
    "open_findings": 1,
    "max_severity": "CRITICAL",
    "uri": "cloudg://assets/sg-admin"
  },
  "findings": [
    {
      "id": "f-ssh-open",
      "title": "Security group allows SSH (22) from 0.0.0.0/0",
      "severity": "CRITICAL",
      "risk_score": 9.5,
      "source_tool": "prowler",
      "resource_id": "sg-admin",
      "resource_arn": "arn:aws:ec2:us-east-1:111111111111:security-group/sg-0admin",
      "asset_id": "sg-admin",
      "asset_name": "sg-admin",
      "compliance_frameworks": [
        "CIS-AWS",
        "PCI-DSS"
      ],
      "is_suppressed": false,
      "cvss_score": null,
      "detected_at": "2026-01-15T12:00:00+00:00",
      "uri": "cloudg://findings/f-ssh-open"
    }
  ]
}

cloudg://findings/summary returned one application/json content item (283 characters).

{
  "dataset": "sample",
  "open_findings": 11,
  "suppressed": 1,
  "severity_breakdown": {
    "CRITICAL": 2,
    "HIGH": 5,
    "MEDIUM": 2,
    "LOW": 1,
    "INFO": 1
  },
  "by_tool": {
    "prowler": 5,
    "scoutsuite": 3,
    "trivy": 1,
    "checkov": 1,
    "iam": 1
  }
}

cloudg://findings/f-ssh-open returned one application/json content item (680 characters).

{
  "id": "f-ssh-open",
  "title": "Security group allows SSH (22) from 0.0.0.0/0",
  "severity": "CRITICAL",
  "risk_score": 9.5,
  "source_tool": "prowler",
  "resource_id": "sg-admin",
  "resource_arn": "arn:aws:ec2:us-east-1:111111111111:security-group/sg-0admin",
  "asset_id": "sg-admin",
  "asset_name": "sg-admin",
  "compliance_frameworks": [
    "CIS-AWS",
    "PCI-DSS"
  ],
  "is_suppressed": false,
  "cvss_score": null,
  "detected_at": "2026-01-15T12:00:00+00:00",
  "uri": "cloudg://findings/f-ssh-open",
  "description": "Security group allows SSH (22) from 0.0.0.0/0.",
  "evidence": "IpPermissions 0.0.0.0/0 tcp 22",
  "remediation": "Restrict 22 to the VPN."
}

cloudg://findings/severity/CRITICAL returned one application/json content item (1220 characters).

{
  "dataset": "sample",
  "severity": "CRITICAL",
  "total": 2,
  "truncated": false,
  "findings": [
    {
      "id": "f-ssh-open",
      "title": "Security group allows SSH (22) from 0.0.0.0/0",
      "severity": "CRITICAL",
      "risk_score": 9.5,
      "source_tool": "prowler",
      "resource_id": "sg-admin",
      "resource_arn": "arn:aws:ec2:us-east-1:111111111111:security-group/sg-0admin",
      "asset_id": "sg-admin",
      "asset_name": "sg-admin",
      "compliance_frameworks": [
        "CIS-AWS",
        "... 1 more"
      ],
      "is_suppressed": false,
      "cvss_score": null,
      "detected_at": "2026-01-15T12:00:00+00:00",
      "uri": "cloudg://findings/f-ssh-open"
    },
    "... 1 more"
  ]
}

cloudg://compliance/CIS-AWS returned one application/json content item (1001 characters).

{
  "dataset": "sample",
  "posture": [
    {
      "framework": "CIS-AWS",
      "controls_evaluated": 4,
      "controls_failing": 3,
      "controls_passing": 1,
      "controls_other": 0,
      "pass_rate": 25.0,
      "open_findings": 6,
      "severity_breakdown": {
        "CRITICAL": 1,
        "HIGH": 3,
        "MEDIUM": 2
      },
      "affected_assets": 5,
      "uri": "cloudg://compliance/CIS-AWS"
    }
  ],
  "failing_controls": [
    {
      "framework": "CIS-AWS",
      "control_id": "5.2",
      "control_title": "No SG allows 0.0.0.0/0 to admin ports",
      "open_findings": 1,
      "max_severity": "CRITICAL"
    },
    {
      "framework": "CIS-AWS",
      "control_id": "1.16",
      "control_title": "IAM trust least privilege",
      "open_findings": 1,
      "max_severity": "HIGH"
    },
    "... 1 more"
  ]
}

cloudg://graph/d3 returned one application/json content item (28639 characters).

{
  "nodes": [
    {
      "id": "org",
      "name": "sample-org",
      "type": "ORGANIZATION",
      "provider": "AWS",
      "region": "global",
      "arn": "arn:aws:organizations::111111111111:organization/o-sample",
      "account_id": "111111111111",
      "is_internet_exposed": false,
      "is_external": false
    },
    {
      "id": "ou-workloads",
      "name": "Workloads",
      "type": "ORG_UNIT",
      "provider": "AWS",
      "region": "global",
      "arn": "arn:aws:organizations::111111111111:ou/o-sample/ou-work",
      "account_id": "111111111111",
      "is_internet_exposed": false,
      "is_external": false
    },
    "... 42 more"
  ],
  "links": [
    {
      "source": "org",
      "target": "ou-workloads",
      "type": "CONTAINS",
      "port_range": "",
      "protocol": "",
      "cidr": "",
      "direction": "ingress",
      "relationship": "",
      "description": ""
    },
    {
      "source": "ou-workloads",
      "target": "acct-prod",
      "type": "CONTAINS",
      "port_range": "",
      "protocol": "",
      "cidr": "",
      "direction": "ingress",
      "relationship": "",
      "description": ""
    },
    "... 53 more"
  ]
}

cloudg://graph/graphml returned one application/graphml+xml content item (33946 characters).

<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
  <key id="d15" for="edge" attr.name="relationship" attr.type="string" />
  <key id="d14" for="edge" attr.name="description" attr.type="string" />
  <key id="d13" for="edge" attr.name="direction" attr.type="string" />
...

cloudg://ontology/turtle returned one text/turtle content item (43748 characters).

@prefix cm: <https://cloudg.io/ontology#> .
@prefix cmp: <https://cloudg.io/property/> .
@prefix cmr: <https://cloudg.io/resource/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

cm:AccessAnalyzer a owl:Class ;
    rdfs:label "AccessAnalyzer" ;
    rdfs:subClassOf cm:CloudResource .

cm:AccessKey a owl:Class ;
    rdfs:label "AccessKey" ;
    rdfs:subClassOf cm:CloudResource .

cm:AccessPoint a owl:Class ;
...

cloudg://schema/asset-types/KMS_KEY returned one application/json content item (150 characters).

{
  "asset_type": "KMS_KEY",
  "family": "Secrets / Keys",
  "note": null,
  "ontology_class": "cm:EncryptionKey",
  "terraform_type": "aws_kms_key"
}

cloudg://schema/edge-types returned one application/json content item (3212 characters).

{
  "SECURITY_GROUP_RULE": {
    "reads_as": "allows traffic",
    "typical": "CIDR -> SG (ingress), SG -> CIDR (egress)",
    "dependency_direction": "none"
  },
  "NACL_RULE": {
    "reads_as": "allows traffic",
    "typical": "network ACL rules",
    "dependency_direction": "none"
  },
  "ROUTE": {
    "reads_as": "routes through / forwards to",
    "typical": "route table -> gateway, DNS record -> load balancer, ingress -> service",
    "dependency_direction": "forward"
  },
  "IAM_TRUST": {
    "reads_as": "may assume",
    "typical": "principal / account / provider -> role",
    "dependency_direction": "forward"
  },
  "IAM_POLICY_ATTACHMENT": {
    "reads_as": "has policy",
    "typical": "user / group / role -> managed policy",
    "dependency_direction": "forward"
  },
  "CONTAINS": {
    "reads_as": "contains",
    "typical": "VPC -> subnet, subnet -> instance, account -> resource",
    "dependency_direction": "reverse"
  },
  "PEERING": {
    "reads_as": "peers with",
    "typical": "VPC -> peering connection -> VPC",
    "dependency_direction": "forward"
  },
  "LOAD_BALANCER_TARGET": {
    "reads_as": "sends traffic to",
    "typical": "load balancer -> target group -> instance",
    "dependency_direction": "forward"
  },
  "INTERNET_EXPOSED": {
    "reads_as": "exposes",
    "typical": "0.0.0.0/0 -> exposed asset",
    "dependency_direction": "none"
  },
  "ATTACHED_TO": {
    "reads_as": "is attached to",
    "typical": "instance -> security group, volume -> instance, ENI -> instance",
    "dependency_direction": "forward"
  },
  "REFERENCES": {
    "reads_as": "uses / points at",
    "typical": "function -> secret, table -> KMS key, queue -> DLQ",
    "dependency_direction": "forward"
  },
  "INVOKES": {
    "reads_as": "triggers / calls",
    "typical": "bucket -> function, queue -> function, rule -> target",
    "dependency_direction": "reverse"
  },
  "USES_IMAGE": {
    "reads_as": "runs the image of",
    "typical": "task definition / workload / function -> registry",
    "dependency_direction": "forward"
  },
  "ASSUMES_ROLE": {
    "reads_as": "runs as",
    "typical": "function, task, node group, instance profile -> role / service account",
    "dependency_direction": "forward"
  },
  "GRANTS_ACCESS": {
    "reads_as": "is granted access to",
    "typical": "principal -> resource its policy names",
    "dependency_direction": "forward"
  },
  "LOGS_TO": {
    "reads_as": "sends logs to",
    "typical": "trail, flow log, LB, function -> log destination",
    "dependency_direction": "forward"
  },
  "PROTECTS": {
    "reads_as": "protects",
    "typical": "WAF -> ALB / API / distribution, firewall -> VPC",
    "dependency_direction": "reverse"
  },
  "MONITORS": {
    "reads_as": "monitors",
    "typical": "Inspector -> instance, GuardDuty -> account, alarm -> resource",
    "dependency_direction": "reverse"
  },
  "MANAGES": {
    "reads_as": "manages",
    "typical": "stack -> resource, ASG -> instance, landing zone -> account",
    "dependency_direction": "reverse"
  },
  "GOVERNS": {
    "reads_as": "governs",
    "typical": "SCP / control / org policy -> OU, account, folder, project",
    "dependency_direction": "reverse"
  }
}

cloudg://docs returned one application/json content item (942 characters).

{
  "available": true,
  "topics": {
    "mcp": "How to use cloudg through MCP",
    "pipeline": "Phases of a cloudg run",
    "cli": "cloudg command-line reference",
    "inputs": "Scanner report formats",
    "outputs": "Files cloudg writes",
    "data-models": "Finding / CloudAsset / NetworkEdge",
    "configuration": "config.yaml reference",
    "python-api": "CloudGEngine and inventory API",
    "recipes": "Integration recipes",
    "authentication": "Cloud credentials",
    "identifiers": "ARN / Azure / GCP / placeholder identifier formats",
    "edges": "NetworkEdge fields",
    "edge-types": "Edge types, direction and dependency semantics",
    "relations": "Declared relations on assets",
    "inventory-summary": "InventoryResult.summary",
    "dependencies": "depends_on / dependents / tree / blast radius",
    "inventory-map": "inventory-map.json format",
    "organization": "Organization / Control Tower topology"
  }
}

cloudg://docs/mcp returned one text/markdown content item (1097 characters).

# Using cloudg through MCP

1. `workspace_status` shows what is loaded. Load data with `load_dataset(path=...)`
   (inventory-map.json, findings.json, scanner output) or collect live with
   `map_inventory` (needs cloud credentials on the server).
2. Orient: `dataset_summary`, `count_assets(group_by=...)`, `findings_summary`.
3. Prioritise: `top_risks`, `internet_exposure`, `attack_paths`.
4. Drill down: `get_asset(ref)`, `findings_for_asset`, `neighbors`, `blast_radius`,
   `dependency_tree`, `find_paths`.
5. Compliance: `compliance_summary`, `list_controls`, `control_status`, `compliance_gaps`.
...

cloudg://policy returned one application/json content item (1138 characters).

{
  "deny_tools": [],
  "deny_resources": [],
  "deny_prompts": [],
  "deny_categories": [],
  "allow_capabilities": [],
  "deny_capabilities": [],
  "name": "open",
  "description": "No transforms, no restrictions. Trusted local experiments only.",
  "hide_denied": true,
  "honor_hints": true,
  "audit": false,
  "audit_size": 1000,
  "transforms": [],
  "input_transforms": [],
  "transform_options": {},
  "detectors": [],
  "disabled_detectors": [],
  "roles": {},
  "rules": [],
  "rate_limits": [],
  "vault": {
    "key_env": "CLOUDG_MCP_VAULT_KEY",
    "scope": "global",
    "ttl_seconds": null,
    "path": null,
    "autosave": false,
    "encrypt": true,
    "entries": 0,
    "namespaces": 0,
    "by_entity": {},
    "key_source": "random",
    "key_id": "d03a61100e65",
    "persist_path": null,
    "counters": {},
    "key_configured": false
  },
  "loaded_from": "profile:open",
  "extends_chain": [],
  "effective_denied_capabilities": [],
  "counters": {
    "allowed": 18
  },
  "available_profiles": [
    "airgapped",
    "audit",
    "... 3 more"
  ]
}

Read errors:

{
  "uri": "cloudg://assets/web-9",
  "error": "ReferenceNotFoundError",
  "code": -32602,
  "message": "No asset matches the reference in this dataset. 5 close matches, see suggestions in the error data. Use find_assets(query=...) to search by name, ARN or tag."
}
{
  "uri": "cloudg://findings/severity/URGENT",
  "error": "ReferenceNotFoundError",
  "code": -32602,
  "message": "Unknown severity; use one of CRITICAL, HIGH, MEDIUM, LOW, INFO"
}
{
  "uri": "cloudg://graph/png",
  "error": "ReferenceNotFoundError",
  "code": -32602,
  "message": "Unknown graph format; use d3, cytoscape, graphml"
}
{
  "uri": "cloudg://docs/nope",
  "error": "ReferenceNotFoundError",
  "code": -32602,
  "message": "Unknown docs topic. Topics: mcp, pipeline, cli, inputs, outputs, data-models, configuration, python-api, recipes, authentication, identifiers, edges, edge-types, relations, inventory-summary, dependencies, inventory-map, organization"
}
{
  "uri": "cloudg://nothing",
  "error": "NotFoundError",
  "code": -32602,
  "message": "Unknown resource: cloudg://nothing"
}

From the command line, cloudg mcp read <uri> prints the text of each content item:

cloudg mcp read 'cloudg://compliance/CIS-AWS' --policy open --dataset sample=./inventory
cloudg mcp read 'cloudg://assets/i-0bast' --dataset sample=./inventory