Skip to content

find_paths

Graph · From docs/MCP_TOOLS.md on GitHub

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

Shortest simple paths from source to target, shortest first, using NetworkX shortest_simple_paths. Enumeration stops at the first path longer than max_depth hops or once max_paths paths are collected. truncated is true only when another path within max_depth exists beyond the ones returned.

Argument Type Default Constraints Description
source string required min length 1 Start asset ref, or 'internet'.
target string required min length 1 End asset ref.
max_depth integer 6 1..12 Longest path (in hops) to return.
max_paths integer 5 1..50 Maximum number of paths, shortest first.
mode string "flow" one of flow, directed, undirected flow: network-flow hops (as the reachability analysis walks them: security groups admit traffic to attached resources) plus identity pivots (ASSUMES_ROLE, IAM_TRUST, GRANTS_ACCESS); directed: edges as collected; undirected: any connection.
dataset string "" Dataset name (see list_datasets). Empty = the active dataset.

Modes: flow (default) is the flow graph, best for "can traffic get from A to B, and which identity can it pivot to"; directed is the relationship graph as collected; undirected ignores direction and answers "are these connected at all". With source: "internet" the walk starts at the virtual __internet__ node linked to every internet entry point.

Each path has length (hops), nodes (hop briefs), edge_types (one per hop, SG_ADMITS for derived flow hops) and summary (names joined by ->). The result also echoes source, target and mode, plus total_found and truncated, and a hint when nothing was found.

From the internet to the orders database:

Called with the arguments below, find_paths returned this structuredContent.

{"source": "internet", "target": "orders-db"}
{
  "dataset": "sample",
  "source": {
    "id": "__internet__",
    "name": "internet",
    "type": "EXTERNAL",
    "external": true
  },
  "target": {
    "id": "orders-db",
    "name": "orders-db",
    "type": "RDS_INSTANCE",
    "provider": "AWS",
    "region": "us-east-1",
    "account_id": "111111111111",
    "arn": "arn:aws:rds:us-east-1:111111111111:db:orders-db",
    "internet_exposed": false,
    "open_findings": 1,
    "max_severity": "MEDIUM",
    "uri": "cloudg://assets/orders-db"
  },
  "mode": "flow",
  "paths": [
    {
      "length": 5,
      "nodes": [
        {
          "id": "0.0.0.0/0",
          "name": "0.0.0.0/0",
          "type": "EXTERNAL",
          "external": true
        },
        {
          "id": "alb-web",
          "name": "web-alb",
          "type": "LOAD_BALANCER",
          "account_id": "111111111111",
          "internet_exposed": true,
          "open_findings": 0
        },
        "... 4 more"
      ],
      "edge_types": [
        "INTERNET_EXPOSED",
        "LOAD_BALANCER_TARGET",
        "LOAD_BALANCER_TARGET",
        "... 2 more"
      ],
      "summary": "0.0.0.0/0 -> web-alb -> web-tg -> web-1 -> app-role -> orders-db"
    },
    {
      "length": 5,
      "nodes": [
        {
          "id": "0.0.0.0/0",
          "name": "0.0.0.0/0",
          "type": "EXTERNAL",
          "external": true
        },
        {
          "id": "alb-web",
          "name": "web-alb",
          "type": "LOAD_BALANCER",
          "account_id": "111111111111",
          "internet_exposed": true,
          "open_findings": 0
        },
        "... 4 more"
      ],
      "edge_types": [
        "INTERNET_EXPOSED",
        "LOAD_BALANCER_TARGET",
        "LOAD_BALANCER_TARGET",
        "... 2 more"
      ],
      "summary": "0.0.0.0/0 -> web-alb -> web-tg -> web-2 -> app-role -> orders-db"
    },
    "... 2 more"
  ],
  "total_found": 4,
  "truncated": false
}

In flow mode the bastion is reachable through its security group; in directed mode it is not, because the collected edge runs from the instance to the group:

Called with the arguments below, find_paths returned this structuredContent.

{"source": "internet", "target": "bastion", "mode": "flow"}
{
  "dataset": "sample",
  "source": {
    "id": "__internet__",
    "name": "internet",
    "type": "EXTERNAL",
    "external": true
  },
  "target": {
    "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"
  },
  "mode": "flow",
  "paths": [
    {
      "length": 2,
      "nodes": [
        {
          "id": "0.0.0.0/0",
          "name": "0.0.0.0/0",
          "type": "EXTERNAL",
          "external": true
        },
        {
          "id": "sg-admin",
          "name": "sg-admin",
          "type": "SECURITY_GROUP",
          "account_id": "111111111111",
          "internet_exposed": false,
          "open_findings": 1,
          "max_severity": "CRITICAL"
        },
        {
          "id": "bastion",
          "name": "bastion",
          "type": "EC2",
          "account_id": "111111111111",
          "internet_exposed": true,
          "open_findings": 1,
          "max_severity": "HIGH"
        }
      ],
      "edge_types": [
        "SECURITY_GROUP_RULE",
        "SG_ADMITS"
      ],
      "summary": "0.0.0.0/0 -> sg-admin -> bastion"
    }
  ],
  "total_found": 1,
  "truncated": false
}

Called with the arguments below, find_paths returned this structuredContent.

{"source": "internet", "target": "bastion", "mode": "directed"}
{
  "dataset": "sample",
  "source": {
    "id": "__internet__",
    "name": "internet",
    "type": "EXTERNAL",
    "external": true
  },
  "target": {
    "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"
  },
  "mode": "directed",
  "paths": [],
  "total_found": 0,
  "truncated": false,
  "hint": "No path within 6 hops in 'directed' mode. Try mode='undirected' or a larger max_depth, or check neighbors() of each end."
}

Related: attack_paths (ranked, many targets at once), neighbors.