Skip to main content
Glama

Azure NeuroMap MCP

ci python license

A read-only MCP server that maps your Azure estate as a graph and tells you, precisely and with evidence, what is exposed, how it is connected, and who can access it.

Every answer cites the exact Azure fields it came from. If something cannot be read, it says unknown and why. It never guesses. See the demo map (synthetic data).

A read-only MCP server that scans Azure and turns every resource into a connected graph: networking (VNets, subnets, NSGs and every rule, NICs, IPs, peerings, routes, gateways, firewalls), data and PaaS (SQL, Managed Instance, PostgreSQL, MySQL, Cosmos DB, Storage, Key Vault, App Service and Functions, AKS, ACR, Redis, Service Bus, Event Hubs, AI services, Search), edge devices (Azure Firewall and policies, Load Balancer, Application Gateway and WAF, VPN / ExpressRoute), managed identities and Azure RBAC. For each resource it states its network access and auth settings precisely, with the source of every fact.

Precision contract

  1. Every fact records its source: arg (Resource Graph) or arm <api-version> (direct GET).

  2. Every verdict lists the exact fields and values it was derived from (because).

  3. Missing or unreadable data gives unknown with the reason (for example ARM read failed (HTTP 403)).

  4. Where Azure documents what an unset field means (Key Vault without networkAcls allows all networks, SQL with no firewall rules denies all), that rule is applied and written into because.

  5. Nothing is inferred from names, tags, naming conventions or connection strings.

  6. No secrets are read: no listKeys, no app settings, no connection strings. Only GET and Resource Graph.

  7. Rules are shown even when they do not apply. A resource with public access disabled still lists its firewall, IP and VNet rules, marked rules_in_effect: false, because they come back the moment access is re-enabled. No allow edges are drawn for them.

  8. A "disable" flag that is not set is reported as not disabled (for example local_auth_disabled), with the reason in notes.

Related MCP server: AWS Cost Saver

How it works

Azure Resource Graph (1 KQL query, paged)  ->  raw snapshot  ->  graph builder  ->  MCP tools
                                                   |                   |
                                           ~/.neuromap/snapshots     HTML "neurosystem" map

Only two Azure calls exist, both read-only: list subscriptions, and query Resource Graph. The raw snapshot is kept so later phases can re-derive new views without re-scanning.

Install

Windows (use one fixed path, so the AI client config never changes on upgrade):

python -m venv C:\Tools\neuromap\.venv
C:\Tools\neuromap\.venv\Scripts\python.exe -m pip install git+https://github.com/KanenasCS/azure-neuromap-mcp
C:\Tools\neuromap\.venv\Scripts\neuromap.exe selftest      # offline, no Azure needed

Linux / macOS:

python3 -m venv ~/.neuromap-venv
~/.neuromap-venv/bin/pip install git+https://github.com/KanenasCS/azure-neuromap-mcp
~/.neuromap-venv/bin/neuromap selftest

First scan

az login --tenant <tenant-id>                 # or managed identity / AZURE_* env vars
neuromap scan -s <subscription-id>            # read-only; prints a summary
neuromap map                                  # offline HTML map, prints the path
neuromap rebuild                              # re-derive the graph from the saved scan (no Azure calls)

Permission needed: Reader on the subscriptions you scan. In the summary check enrichment_error_count: 0 and collection_errors: [].

Connect an AI client

Claude Desktop. Add to claude_desktop_config.json:

{ "mcpServers": { "azure-neuromap": {
    "command": "C:\\Tools\\neuromap\\.venv\\Scripts\\neuromap-mcp.exe" } } }

On Windows the Claude Desktop installer is an MSIX package, and the file it reads is %LOCALAPPDATA%\Packages\Claude_<id>\LocalCache\Roaming\Claude\claude_desktop_config.json (not only %APPDATA%\Claude\...). Quit Claude Desktop from the tray before editing, and check Settings > Developer shows the server as running.

VS Code (.vscode/mcp.json):

{ "servers": { "azure-neuromap": { "type": "stdio",
  "command": "C:\\Tools\\neuromap\\.venv\\Scripts\\neuromap-mcp.exe" } } }

Upgrade

Quit the AI client first (Windows cannot replace a running .exe), then:

C:\Tools\neuromap\.venv\Scripts\python.exe -m pip install --upgrade --no-deps --force-reinstall git+https://github.com/KanenasCS/azure-neuromap-mcp

Saved graphs from an older version are rebuilt from the raw scan automatically.

Tools

Tool

What it answers

scan_infrastructure

Scan now: all resources, RGs, RBAC, access settings (enrich=false skips ARM child reads)

infra_summary

Counts by kind, public-endpoint states, RBAC status, enrichment errors

find_resource

Name, partial name, resource ID or IP to node, plus the subnet that contains an IP

get_node

One resource plus everything linked to it (depth 1 to 3)

get_access

Public-endpoint verdict, because, rules, allowed IPs/subnets, private endpoints, auth, TLS, sources, unknowns

list_public_exposure

Resources by verdict (default: open to all networks)

who_has_access

RBAC role assignments applying to a resource, direct and inherited (resource, RG, subscription, management groups, root), per-scope coverage (uncollected = unknown, never zero), capabilities from each role's actions/notActions (assign roles, write, delete), plus data-plane auth

identity_permissions

Roles held by a resource's system and user-assigned identities

firewall_rules

Azure Firewall or policy rules in processing order, parent policy inheritance, IP groups expanded, threat intel / IDPS / DNS proxy

search_firewall_rules

Search all firewalls by port, source, destination, FQDN (wildcards), action, rule type

ingress_paths

Every declared way in: firewall DNAT, public LB rules and NAT rules, App Gateway routes with effective WAF, public IPs on NICs

route_for

UDRs for a subnet/NIC/VM/VMSS with each next hop resolved to the resource that owns the IP

hybrid_connectivity

VPN/ER gateways, connections and status, on-prem ranges, ER peerings, P2S pools, spokes using the gateway

nsg_rules_for

NSG layers on a VM/NIC/PE/public IP/subnet (or the subnet of AKS, MI, ...) in evaluation order

search_nsg_rules

Estate-wide NSG rule search, e.g. port 3389 + source internet + Allow

export_map

Writes the offline interactive map and returns the path

Prompts: map_my_infra, explain_resource, access_review, internet_ingress_review. Resource: neuromap://summary.

Access verdicts

public_endpoint is one of disabled, vnet_injected, restricted, all_networks, all_networks_with_denies, enabled_no_allow_rules, gated_by_nsg, perimeter_controlled, no_inbound_endpoint, decided_per_app, unknown, not_evaluated.

Type

Fields evaluated

Extra ARM reads

Storage

publicNetworkAccess, networkAcls (default action, IP, VNet, resource rules, bypass), shared key, blob public access, TLS

none

Key Vault

publicNetworkAccess, networkAcls, RBAC mode, access policies

none

SQL server

publicNetworkAccess, firewall rules (union checked for full IPv4), 0.0.0.0 Azure rule, VNet rules (shown but marked not in effect when public access is disabled), Entra admin and Entra-only from their own child resources, TLS

server, firewallRules, virtualNetworkRules, administrators, azureADOnlyAuthentications (2021-11-01)

SQL Managed Instance

publicDataEndpointEnabled, subnet, proxy, Entra-only, TLS

none

PostgreSQL / MySQL flexible

delegated subnet, publicNetworkAccess, firewall rules, Entra/password auth

firewallRules (2022-12-01 / 2021-05-01)

Cosmos DB

publicNetworkAccess, IP rules, VNet filter and rules, bypass, local auth, TLS

none

App Service / Functions

publicNetworkAccess, access restrictions (first-match, default action), SCM site, VNet integration, FTP/SCM basic auth, TLS, FTPS

config/web, basicPublishingCredentialsPolicies (2023-01-01)

AKS

private cluster, authorized IP ranges, node subnets, Entra/Azure RBAC, local accounts, network plugin/policy

none

ACR

publicNetworkAccess, network rule set, SKU rule, admin user, anonymous pull

none

Redis

publicNetworkAccess, VNet injection, firewall rules, access-key auth, non-SSL port, TLS

firewallRules (2022-06-01)

Service Bus / Event Hubs

publicNetworkAccess, network rule set, trusted services, local auth, TLS

networkRuleSets/default (2021-11-01)

AI services / OpenAI

publicNetworkAccess, networkAcls, local auth, outbound restriction

none

AI Search

publicNetworkAccess, IP rules, local auth

none

Managed disks

publicNetworkAccess, networkAccessPolicy (AllowAll / AllowPrivate / DenyAll), disk access, live export SAS (diskState = ActiveSAS), data access auth mode. Scope is export/import through SAS URLs

none

Container Apps

Environment internal/external (internal overrides any app's external ingress), infrastructure subnet, app ingress external, IP restrictions (all-Allow or all-Deny semantics), insecure HTTP, client certs

none

Logic Apps (Consumption)

Inbound triggers in the definition (Request, ApiConnectionWebhook, HttpWebhook), with trigger types cited, accessControl.triggers.allowedCallerIpAddresses ([] = only other Logic Apps), OAuth policies, workflow state

none

Log Analytics / App Insights

publicNetworkAccessForIngestion and ForQuery (verdict = most open endpoint, both cited), local auth

none

Data Collection Endpoints

networkAcls.publicNetworkAccess (Enabled / Disabled / SecuredByPerimeter)

none

Automation

publicNetworkAccess (boolean) for webhooks and Hybrid Worker endpoints, local auth

none

Purview

publicNetworkAccess, managed resources public access

none

Any other type

raw publicNetworkAccess and private endpoint connections, marked not_evaluated

none

Edge devices

Device

What is turned into facts and edges

Extra ARM reads

Azure Firewall

Policy chain (base policies), rule collection groups, DNAT/network/application rules in processing order, IP groups expanded, classic rule collections, threat intel, IDPS, DNS proxy, vWAN hub IPs. DNAT rules become DNAT_FORWARDS edges to the translated target, and INGRESS_ANY_SOURCE from the Internet only when the rule accepts any source

ruleCollectionGroups (2023-09-01)

Load Balancer

Frontends, backend pools (NIC, VMSS and IP-based members, deduplicated when Azure lists a node twice), owning AKS cluster and its power state (from the cluster's nodeResourceGroup), LB rules (incl. HA ports, floating IP), inbound NAT rules (single port and port-range v2), outbound rules, probes. Each rule becomes LB_FORWARDS frontend to member; public rules whose pool is empty (for example a stopped cluster) are still listed by ingress_paths with 0 backend instances

none

Application Gateway

Listeners (port, protocol, host names), basic and path-based routing, redirects, backend pools (NIC, IP, FQDN matched to web app and Container App host names), HTTP settings, SSL policy. WAF per route, resolved in order: path rule policy, listener policy, gateway policy, legacy WAF config, and "not available" when the SKU tier is not WAF

none

Route tables

Each VirtualAppliance next hop IP resolved to the firewall, NVA NIC or internal LB that owns it (NEXT_HOP). Blackhole routes (None) flagged

none

VPN / ExpressRoute

Gateway type, SKU, active-active, BGP, point-to-site pool and auth, S2S / VNet-to-VNet / ER connections with status and BGP, local network gateway on-prem ranges, ER circuit provider and peerings, spokes that use the gateway through peering

none

VM Scale Sets

Subnet, NIC-configuration NSG, LB and App Gateway pool membership, instance public IPs flag

none

Anything referenced but not owned by a scanned resource becomes an explicit node such as ip:10.9.9.9 or fqdn:api.example.com, marked outside scan, never matched by guesswork. Connection shared keys and certificates are never read.

A verdict describes the resource's own network layer. It does not claim a given client can connect end to end, because client-side DNS, routes, NSGs and firewalls are separate layers.

Relationship types

Network: CONTAINS IN_SUBNET PROTECTED_BY HAS_NIC HAS_PUBLIC_IP PEERED_WITH ROUTES_VIA EGRESS_VIA CONNECTS_TO MEMBER_OF BALANCES_TO USES_POLICY

Access: OPEN_TO_ALL_NETWORKS (Internet node to resource), IP_RULE_ALLOWS (a scanned public IP is inside an allow rule), VNET_RULE_ALLOWS (subnet allowed by a VNet rule). Allow edges are drawn only for restricted resources, where they actually change who can connect.

Platform and identity: VNET_INTEGRATION HOSTED_ON USES_IDENTITY MANAGED_BY HAS_ROLE (one edge per role assignment).

Edge: DNAT_FORWARDS LB_FORWARDS APPGW_ROUTES NEXT_HOP HYBRID_CONNECTION INGRESS_ANY_SOURCE INHERITS_FROM USES_IP_GROUP ATTACHED_TO IN_HUB

Generic: REFERENCES for any other resource ID written in a resource's properties, with the exact property path (for example properties.parameters.$connections.value.sql.connectionId).

Data handling

Snapshots and maps describe your network in detail. They live in ~/.neuromap (change with NEUROMAP_HOME). Treat that folder as sensitive and do not commit it. The map HTML embeds Cytoscape.js (MIT, see static/cytoscape.LICENSE) and makes no network calls.

Known limits

  • RBAC: assignments above the subscription are read with roleAssignments?$filter=atScope() (Reader is enough); if that call fails, those scopes are reported as not collected. Active assignments only. Deny assignments, PIM eligible roles and group membership are not expanded, and users/groups/service principals are shown by object ID (no Microsoft Graph calls).

  • Networking is declared configuration. Service tags and ASG membership are not expanded, and routes and firewalls are not evaluated for end-to-end reachability.

  • Not evaluated yet: Azure-computed effective routes and system/BGP routes (needs the effectiveRouteTable action, which Reader cannot call), NSG flow logs, Front Door, Traffic Manager, Virtual WAN routing intent, App Gateway rewrite rules and per-URI WAF policies on path maps beyond the path rule level.

  • ARM enrichment makes a few GETs per SQL server, web app, flexible server, Redis cache and Service Bus/Event Hubs namespace. Failures become unknown, never guesses.

  • Map rendering takes around 15 seconds at 8,000+ nodes. Use the legend to hide noisy kinds.

  • Validation. 151 offline checks (synthetic fixtures shaped like Resource Graph and ARM responses, a mocked Azure API for the collector, and order-independence tests) run on Linux and Windows, Python 3.10 to 3.14. Every evaluator was also compared field by field with the Azure CLI on a live estate of 100+ resources; the fixes that produced are in CHANGELOG.md.

Roadmap

  • Phase 2, security overlay: Defender for Cloud plan coverage and recommendations, DDoS, WAF mode, NSG flow logs, diagnostic settings, per node.

  • Phase 3, reasoning: chain the declared layers (DNAT or LB, then UDR, then firewall rule, then NSG) into end-to-end path verdicts, blast radius, and snapshot diffs ("what changed since last week").

Security and contributing

Read SECURITY.md before your first scan. Scans describe your environment in detail and must never be shared. Contributions follow the precision contract in CONTRIBUTING.md.

License

MIT. Cytoscape.js is vendored under its own MIT license (src/neuromap/static/cytoscape.LICENSE).

Available Tools

16 tools
export_mapA
Read-only

Write the interactive offline 'neurosystem' HTML map of the current snapshot and return its path.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint, destructiveHint=false and openWorldHint=false, so the safety profile is largely covered. The description usefully discloses that the output is an HTML artifact and that the return value is a path, but it omits where the file is written, whether an existing file is overwritten, and any size/time cost. The 'Write' verb sits in mild tension with readOnlyHint=true, though for an export tool the write is artifact generation rather than mutation of the source snapshot.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero filler, front-loaded on the verb and artifact, and ending with the return value. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with no output schema, the description covers what it produces (an offline interactive HTML map) and what it returns (the path), which is the essential information. Minor gaps remain around the write location and overwrite behavior, but nothing blocks a correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there are no semantics to document and the baseline is 4. The description correctly implies no inputs are required beyond the 'current snapshot' context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb ('Write') and a concrete artifact ('the interactive offline neurosystem HTML map of the current snapshot'), which clearly separates it from the query-oriented siblings like get_node or infra_summary. It does not name a sibling explicitly, but the deliverable is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: an agent can infer this is the tool to call when it needs a shareable/offline visualization of the snapshot. There is no statement of when to prefer it over the sibling query tools and no prerequisites (e.g., whether the snapshot must exist or be current).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_resourceA
Read-onlyIdempotent

Find nodes by full resource id, IP address (private or public), exact or partial name.

kind filters results: network kinds (vnet, subnet, nsg, nic, vm, vmss, pip, pe, lb, appgw, firewall, fwpolicy, wafpolicy, ipgroup, vnetgw, lng, ercircuit, gwconnection, ...), data/PaaS kinds (storage, keyvault, sql-server, sql-db, sql-mi, postgres, mysql, cosmos, webapp, aks, acr, redis, servicebus, eventhub, cognitive, search, uami), or the short type of any other resource (e.g. 'logic/workflows'). For an IP, declared ranges containing it are also returned (subnets, on-premises ranges from local network gateways, point-to-site pools).

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo
limitNo
queryYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description adds genuine behavioral value beyond that: an IP query also returns the declared ranges containing it (subnets, gateway on-prem ranges, P2S pools), which tells the agent the result set is broader than a single-node match.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The identifier forms are front-loaded in the first sentence, followed by the kind taxonomy and the IP-expansion note. The kind list is long but every entry is load-bearing as an allowed filter value; structure is clean with no filler prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries return-value duty and partially does so by explaining IP-expansion behavior. Query, kind and the matching modes are covered; only the limit/count semantics are absent, leaving a small gap for a lookup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full burden, and it does so for two of three params: it defines query's accepted identifier forms and essentially enumerates kind's allowed values. The third param, limit (default 20), is never mentioned, so compensation is strong but incomplete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('find') and resource ('nodes') and enumerates the three identifier types the query accepts (full resource id, IP, exact/partial name). It does not, however, contrast itself with siblings like get_node, which also looks up nodes, so the agent must infer the find-vs-fetch distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: the tool is for locating a node when you have an identifier of some kind. The long kind filter list conveys intended scope, but there is no explicit statement of when to use this versus get_node or scan_infrastructure, nor any prerequisite or exclusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

firewall_rulesB
Read-onlyIdempotent

Azure Firewall (or Firewall Policy) rules in processing order: DNAT, network, application. Parent-policy rule collection groups come first. IP groups are expanded. Includes threat intel, IDPS and DNS proxy settings, and classic (non-policy) rules. Missing policy data is listed as unknown.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this a read-only, idempotent, non-destructive operation, so the safety profile is covered. Beyond that, the description adds meaningful behavioral context about the returned data: expansion of IP groups, parent-policy groups first, inclusion of threat intel/IDPS/DNS proxy settings and classic rules, and that missing policy data is reported as unknown.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, front-loaded with the processing order that matters most for interpretation. Each sentence conveys a distinct fact (ordering, policy precedence, IP group expansion, included settings) with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does a fair job describing returned contents and ordering, but it omits what 'target' accepts and how this differs from search_firewall_rules. For a tool with only one param and a sibling overlap, more routing and parameter detail is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single required 'target' parameter, and the description says nothing about it — not its format, accepted values, or whether it identifies a subscription, firewall, or policy. With one required param and no schema text, the description should compensate but does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (Azure Firewall / Firewall Policy rules) and details its ordering (DNAT, network, application) and contents, so the agent knows exactly what it returns. However, it never states the operation explicitly (list/get) and does not distinguish itself from the close sibling search_firewall_rules.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives, despite search_firewall_rules being an obvious sibling for filtered lookups. The description describes output content only and gives no trigger conditions or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_accessB
Read-onlyIdempotent

Network access verdict for one resource (SQL, Storage, Key Vault, Cosmos, App Service, AKS, ACR, Redis, PostgreSQL, MySQL, Service Bus, Event Hubs, AI services, Search, ...).

Returns public_endpoint (disabled | vnet_injected | restricted | all_networks | ...), because (exact fields used), network rules, allowed IPs/subnets, private endpoints, auth settings (Entra-only, local auth, shared key), TLS, per-fact sources, and unknowns.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive. The description adds real behavioral value by enumerating the categories of facts returned (public_endpoint values, network rules, private endpoints, auth settings, TLS, per-fact sources, unknowns), which tells the agent what 'verdict' entails beyond a simple boolean.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Compact and front-loaded: the first sentence declares the verdict, the second enumerates returned fields. The long resource enumeration is slightly noisy but justified as scope disclosure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, so the description's field enumeration is useful. However, with 0% parameter coverage and no usage guidance, an agent still cannot confidently call the tool correctly on the first attempt without probing 'target' semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the single parameter 'target' is never explained in the description. An agent cannot tell whether target is a resource ID, a name, an FQDN, or an ARM path. The resource-type list hints at supported targets but doesn't clarify the expected format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Network access verdict for one resource' with an enumerated list of supported resource types. It's clear what the tool does, though it doesn't explicitly differentiate from siblings like who_has_access or list_public_exposure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Purpose is implied by the resource list and the 'access verdict' framing, but the description never states when to use this tool versus alternatives such as who_has_access (identity-level) or list_public_exposure (fleet-level). No exclusions or routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_nodeB
Read-onlyIdempotent

Full detail of one node plus everything linked to it, up to depth 3.

ref: resource id, IP or unique name. Relationships include CONTAINS, IN_SUBNET, PROTECTED_BY, HAS_NIC, HAS_PUBLIC_IP, PEERED_WITH, ROUTES_VIA, EGRESS_VIA, CONNECTS_TO, MEMBER_OF, BALANCES_TO, USES_POLICY, VNET_INTEGRATION, HOSTED_ON, USES_IDENTITY, MANAGED_BY, HAS_ROLE, OPEN_TO_ALL_NETWORKS, VNET_RULE_ALLOWS, IP_RULE_ALLOWS, and REFERENCES (any other ARM id found in properties, with its exact property path).

ParametersJSON Schema
NameRequiredDescriptionDefault
refYes
depthNo

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds useful context about traversal depth (up to 3) and enumerates relationship types, but does not describe return format, pagination, or error behavior beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and ref semantics are front-loaded, which is good. However, the description then lists 23 relationship types in a dense block, which is informative but bulky and could be summarized or moved to an output schema if one existed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and low schema coverage, the description adequately explains what is returned: full node detail plus linked entities and their relationship types. It still lacks explicit usage guidance versus siblings and precise depth semantics, but overall it is sufficient for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates partially by explaining that ref accepts a resource id, IP, or unique name. It also states a maximum depth of 3, but does not explain what the depth parameter controls or how values 1–3 differ in traversal behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific operation: returning full detail of a single node and all linked entities up to depth 3. It clearly identifies the resource (one node) and scope, but does not differentiate from sibling tools like find_resource or scan_infrastructure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'Full detail of one node plus everything linked to it,' which suggests this is for deep inspection of a single known node. However, there is no explicit when-to-use guidance or comparison with alternatives such as find_resource or infra_summary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hybrid_connectivityB
Read-onlyIdempotent

VPN and ExpressRoute: each gateway with its VNet, SKU, BGP and point-to-site settings, its connections (type, status, BGP) and remote side (on-prem ranges, gateway IP, ER peerings), and the spoke VNets that use it through peering.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds nothing behavioral on top - no indication of whether this returns a full dump or filtered view, no scope/pagination notes, no mention of potential size.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with every clause carrying real content about covered entities, and the primary subject (VPN and ExpressRoute) is front-loaded. It is a verbless fragment, which slightly hurts readability but not length or focus.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description must stand in for the return value, and it does outline the entity/attribute coverage reasonably well. However, it gives no sense of result structure, breadth, or how multiple gateways/connections are grouped, which matters for a cross-cutting connectivity view.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to clarify; the baseline of 4 applies. No parameter-related information is missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description enumerates the exact resources covered (VPN/ExpressRoute gateways, VNet, SKU, BGP, point-to-site, connections, remote side, spoke VNets via peering), which makes the domain unambiguous. It lacks an explicit verb such as 'returns' or 'maps', so the agent must infer this is a read/aggregation tool, and no sibling is named for contrast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus alternatives such as infra_summary, route_for, or export_map, and no prerequisites or scope conditions. The agent is left to infer usage purely from the subject matter.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

identity_permissionsC
Read-onlyIdempotent

What a resource's system-assigned and user-assigned managed identities hold: roles and scopes.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes

TDQS

C2.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered. The description adds useful context about what is returned (roles and scopes for managed identities) but does not disclose behavioral traits like inheritance, pagination, or required permissions. Given annotation coverage, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, short sentence and is front-loaded with the returned data. However, it is a noun phrase fragment rather than a complete instructive sentence, which slightly reduces its usability. It is concise but not optimally structured for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has one required parameter and no output schema. The description states what data is returned but does not explain the 'target' parameter, the output structure, or any usage context. Although annotations cover safety, critical details for correct invocation are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the sole parameter 'target' has no description in the schema. The description indirectly suggests that 'target' refers to a resource, but it does not explain the expected format, scope, or any constraints. With one undocumented parameter, the description falls short of compensating for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the returned data precisely — roles and scopes held by a resource's system-assigned and user-assigned managed identities — and thus distinguishes itself from generic access-related siblings. However, it is a noun fragment with no action verb, leaving an agent to infer that this is a read operation. The purpose is understandable but not stated as an action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance is provided. The description does not mention alternatives such as get_access or who_has_access, nor does it indicate prerequisites or scenarios where this tool is appropriate. The agent is left to guess based on the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

infra_summaryB
Read-onlyIdempotent

Counts by resource kind and relationship, scan time, subscriptions, unattached NSGs and public IPs.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint, idempotentHint, and destructiveHint=false, so the description need not cover safety. It adds value by specifying the summary contents, which is beyond the annotations. However, it doesn't disclose whether the counts are live or cached, the scope of the scan, or any performance characteristics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, dense sentence that front-loads the primary content (counts by kind/relationship) and then lists additional metrics. No superfluous wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only summary tool with rich annotations, the description is adequate but lacks details on scope (e.g., entire subscription? all subscriptions?) and output format. Without an output schema, it should specify what exact fields are returned, not just a list of concepts. Missing guidance on how it fits into the broader toolset reduces completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the baseline is 4. The description correctly implies no input is required, aligning with the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the resource being counted ('resource kind and relationship') and lists the specific summary metrics it returns (scan time, subscriptions, unattached NSGs, public IPs). It distinguishes itself from siblings like scan_infrastructure or find_resource by being a summary tool, though it doesn't explicitly name an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this summary versus drilling into specific resources via the many sibling tools (e.g., scan_infrastructure, find_resource). An agent must infer that this is an initial overview, but the description provides no explicit when-to-use or when-not-to-use instructions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ingress_pathsA
Read-onlyIdempotent

Every declared ingress path: firewall DNAT (with allowed sources), public load balancer rules and inbound NAT rules, App Gateway listener -> backend routes (with effective WAF mode), and public IPs attached directly to NICs.

target: limit to paths into or through one resource (VM, NIC, firewall, LB, App Gateway, IP). port: limit to a frontend port. include_private: also show internal LB / private App Gateway listeners.

ParametersJSON Schema
NameRequiredDescriptionDefault
portNo
targetNo
include_privateNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive, so the safety profile is covered. The description adds genuine value beyond that: it enumerates exactly which path constructs are gathered and notes that it reports effective WAF mode and allowed DNAT sources, telling the agent what depth of detail to expect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the return scope and then lists the three parameters in compact form with no filler. The enumeration sentence is long but every item earns its place by telling the agent what is covered.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must convey what comes back, and it does by naming the path categories and the WAF/source detail. For a complex connectivity-inventory tool with three optional filters, this is close to sufficient, missing only hints on result shape or how targets are resolved.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter burden, and it largely does: target is explained as scoping to one resource (with the resource types listed), port as a frontend-port filter, and include_private as also surfacing internal LB / private App Gateway listeners. It stops short of format details such as whether target takes a name or an ID.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names the resource (ingress paths) and enumerates the exact path categories returned: firewall DNAT with allowed sources, public LB rules, inbound NAT, App Gateway listener->backend routes with effective WAF mode, and NIC-attached public IPs. This is specific enough to distinguish it from narrower siblings like firewall_rules or list_public_exposure, though it never explicitly names those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The three parameter lines imply usage (scope to one resource, filter by port, opt into private listeners), but there is no explicit when-to-use vs. when-to-use-an-alternative guidance, no prerequisites, and no exclusions relative to the many overlapping sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_public_exposureA
Read-onlyIdempotent

List resources by public-endpoint verdict. Default: all_networks and all_networks_with_denies.

states: any of disabled, vnet_injected, restricted, all_networks, all_networks_with_denies, enabled_no_allow_rules, gated_by_nsg, perimeter_controlled, no_inbound_endpoint, decided_per_app, unknown, not_evaluated. kind: e.g. storage, keyvault, sql-server, webapp, cosmos, aks, acr, redis, disk, containerapp, aca-env, logicapp, loganalytics, appinsights, dce, automation, purview.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo
limitNo
statesNo

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description adds the default-verdict scoping, but reveals nothing about result shape, pagination, or what a 'verdict' means — modest added value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose sentence followed by two compact value lists; the enumerated lists are long but each token is informative. No filler prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and all-optional params, the description adequately defines the two filter dimensions. It falls slightly short on the limit parameter and on how verdicts map to returned fields, but covers enough to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the param burden. It enumerates all valid states and typical kind values, which is genuine compensation, though it never mentions the limit parameter's default or meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: list resources filtered by public-endpoint verdict. An agent can identify the operation, but the description never contrasts this with siblings like scan_infrastructure or infra_summary, so differentiation is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the default filter behavior (all_networks and all_networks_with_denies), which implies when results appear, but gives no explicit when-to-use-this-vs-alternative routing against the 15 sibling tools and no prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

nsg_rules_forA
Read-onlyIdempotent

Every NSG layer on a VM, NIC, private endpoint, public IP or subnet, in Azure evaluation order.

Inbound shows subnet NSG then NIC NSG. Outbound shows NIC NSG then subnet NSG. Rules are sorted by priority, default rules included.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: Azure evaluation order, the subnet-then-NIC vs NIC-then-subnet asymmetry for inbound/outbound, priority sorting, and inclusion of default rules. It does not cover permissions or response size, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the scope, then the ordering semantics. No filler, and the line breaks map cleanly to distinct facts an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with no output schema, the description tells the agent what comes back (all NSG layers, sorted by priority, default rules included) and in what evaluation order. The one missing piece is the target identifier format, which is the sole input and is undocumented in both schema and description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single required 'target' parameter, so the description must compensate. It partially does by enumerating the accepted target kinds (VM, NIC, private endpoint, public IP, subnet), but it gives no syntax for how a target is identified (resource ID vs name vs IP), leaving a real gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the resource (every NSG layer attached to a VM, NIC, private endpoint, public IP or subnet) and the scope of the result (all layers, in Azure evaluation order), which is a specific verb+resource. It does not explicitly contrast with the sibling search_nsg_rules, so an agent must infer that this tool is target-scoped rather than a global rule search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the target scoping ('every NSG layer on a VM, NIC, ...'), which suggests this is the tool to call when you know the resource and want its effective NSG rules. However, there is no explicit when-to-use guidance and no mention of the sibling search_nsg_rules as the alternative for cross-resource rule lookup.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

route_forB
Read-onlyIdempotent

User-defined routes that apply to a subnet, NIC, VM, VMSS or subnet-injected service, with each VirtualAppliance next hop resolved to the resource that owns that IP (firewall, NVA, internal LB), or to an explicit 'ip:x' node when no scanned resource owns it.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes

TDQS

B3.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the description's value-add is the resolution behavior: next hops are mapped to the owning resource (firewall, NVA, internal LB) or fall back to an explicit 'ip:x' node. That is genuine behavioral detail an agent cannot get from the annotations or schema. It does not say what happens when the target is unknown or over-broad, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with no filler, and the core subject (user-defined routes) is front-loaded. It is dense with nested clauses for a one-parameter tool, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining the return value, and it does describe next-hop resolution. However, for a query tool it omits the target format, whether multiple routes are returned, and any error semantics, so an agent can select the tool but may not invoke it with a correctly-shaped argument.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single 'target' parameter, so the description must compensate. It partially does by listing the kinds of resources a route can apply to (subnet, NIC, VM, VMSS, injected service), hinting at accepted target values, but it never states whether target is a resource ID, name, or IP, or whether a type qualifier is required. This is partially compensating, not fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (user-defined routes) and the scope of application (subnet, NIC, VM, VMSS, injected service), so an agent can tell roughly what comes back. But it never states the action verb ('list'/'get') nor connects it to the 'route_for' name, leaving the operation type implied rather than stated. It also does not differentiate itself from the similarly-shaped sibling nsg_rules_for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as nsg_rules_for or ingress_paths. The agent must infer from the name alone that this is the route-lookup companion to those tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_infrastructureA
Read-onlyIdempotent

Scan Azure (read-only) and rebuild the graph: every resource, resource groups, RBAC role assignments, and access settings.

Uses DefaultAzureCredential (az login, managed identity, env vars). Needs Reader. subscription_ids: limit the scan; omit to scan every enabled subscription visible. enrich: also read child settings Resource Graph lacks (SQL/PostgreSQL/MySQL/Redis firewall rules, App Service access restrictions, Service Bus/Event Hubs network rules). Without it those verdicts are 'unknown'.

ParametersJSON Schema
NameRequiredDescriptionDefault
enrichNo
subscription_idsNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations' readOnly/idempotent/openWorld profile, it discloses concrete operational requirements: DefaultAzureCredential sourcing (az login, managed identity, env vars) and Reader permission level, plus the downstream consequence that skipping enrich leaves certain verdicts 'unknown'. This is meaningful context an agent cannot get from structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Opening line gives the action and scope, followed by tightly grouped auth requirements and per-parameter notes. Every sentence adds information; no filler or repetition of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description covers the operation, auth, permissions, and both parameters adequately. It does not say what the tool returns or how to confirm the rebuild succeeded, which is the main remaining gap for a heavyweight ingestion call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full burden, and it does: subscription_ids ('limit the scan; omit to scan every enabled subscription visible') and enrich (child settings Resource Graph lacks, with the specific resource types listed). Both parameters are fully explained with defaults and consequences.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (scan/rebuild) and enumerates exactly what is ingested: resources, resource groups, RBAC role assignments, and access settings. This scope enumeration clearly separates it from the read-only query siblings like find_resource or who_has_access.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the effect of both parameters ('omit to scan every enabled subscription', enrich adds child settings), which implies usage, but never states when to run this versus the many sibling query tools, nor when not to run a full scan. Usage is inferred rather than prescribed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_firewall_rulesB
Read-onlyIdempotent

Search every firewall's effective rules.

port: destination port (ranges and '*' match). source/destination: IP, CIDR, service tag or 'internet' (matches *, 0.0.0.0/0). fqdn: matched against target FQDN patterns (wildcards honored). action: Allow, Deny or DNAT. rule_type: dnat, network or application.

ParametersJSON Schema
NameRequiredDescriptionDefault
fqdnNo
portNo
limitNo
actionNo
sourceNo
rule_typeNo
destinationNo

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safe-read profile is covered. The description adds the useful detail that it returns 'effective' rules across all firewalls and explains filter matching, but says nothing about result limits, pagination, or default behavior for the limit parameter.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in one line, followed by compact per-parameter notes with no filler. Efficient and readable, though the bare parameter list reads slightly like notes rather than prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers most filter parameters well for a 7-param tool with no output schema, but omits the limit/pagination semantics and does not explain what distinguishes 'effective rules' from raw configured rules. Adequate but with a visible gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage the description must carry the load, and it does: it defines port (ranges and '*'), source/destination (IP/CIDR/service tag/'internet'), fqdn (wildcards), action values (Allow/Deny/DNAT), and rule_type values (dnat/network/application). Only the limit parameter (default 200) goes undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('search every firewall's effective rules'), which is clearer than a bare name restatement. However, it does not differentiate from siblings such as firewall_rules, search_nsg_rules, or nsg_rules_for, so the agent cannot tell which to pick from the text alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no named alternatives despite several overlapping siblings (firewall_rules, search_nsg_rules). The description documents matching syntax but never says when this tool should be chosen over the alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_nsg_rulesA
Read-onlyIdempotent

Search NSG rules across the whole estate, with what each NSG is attached to.

port: destination port, matched against single ports, ranges and '*'. source/destination: a CIDR or IP (overlap match), a service tag like 'VirtualNetwork', or 'internet' to match Internet, *, 0.0.0.0/0 and ::/0. access: Allow or Deny. direction: Inbound or Outbound. protocol: Tcp, Udp, Icmp.

ParametersJSON Schema
NameRequiredDescriptionDefault
portNo
limitNo
accessNo
sourceNo
protocolNo
directionNo
destinationNo
include_defaultNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is fully covered elsewhere. The description does add genuinely useful matching semantics (port range/'*', CIDR overlap, service tags, 'internet' expansion) which is behavior beyond the annotations. It says nothing about pagination or the meaning of the limit/default cap, which matters for an estate-wide search.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-sentence scope statement followed by a compact field glossary; every line carries matching semantics. Slightly list-like but appropriately sized for eight undocumented parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only search with no output schema, the description is functionally adequate but incomplete: it omits what the result set contains beyond 'what each NSG is attached to', never explains limit/default-200 truncation or include_default, and doesn't say whether results are filtered or full-fidelity. Those omissions could cause a caller to under- or over-interpret a capped result set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 8 parameters, so the description carries the burden and does so well for six of them, defining exact value semantics (port, source/destination match modes, access, direction, protocol enumerated values). limit and include_default receive no explanation, which is a real gap but does not erase the strong compensation on the filter parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Search) and resource (NSG rules) plus an unusual scope qualifier: the whole estate, with attachment context. That scope distinguishes it from the narrower sibling nsg_rules_for, but the description never names that or any other alternative, so differentiation is only implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'across the whole estate' implies the estate-wide query context and the filter list implies when each filter applies, but there is no explicit when-to-use / when-not-to-use guidance and no mention of siblings like nsg_rules_for or firewall_rules. Usage is inferable rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

who_has_accessB
Read-onlyIdempotent

Active Azure RBAC role assignments that apply to a resource: on the resource, its parent resources, its resource group, subscription, management groups and root, marked inherited or direct. scope_coverage says per scope whether assignments were collected (a scope that was not collected is unknown, never zero). Each assignment has capabilities computed from the role definition's actions/notActions: assign_roles, write_resource, delete_resource. Also returns data-plane auth facts (Key Vault access policies, SQL Entra admin, ...).

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive, closed-world behavior. The description adds important semantics that annotations do not: inherited vs direct assignments, the scope_coverage caveat that missing data is unknown rather than zero, computed capabilities (assign_roles, write_resource, delete_resource), and data-plane auth facts. These are substantial behavioral details beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded and each sentence carries information: scope of assignments, coverage caveat, computed capabilities, and additional data-plane facts. It is somewhat packed, but no sentence is wasted for a tool of this complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description does some of the work of explaining the return shape (assignments with inherited/direct flags, capabilities, scope_coverage, data-plane facts). That is helpful, but the description does not cover pagination, error behavior, or how to interpret the output fully. Given the complexity and lack of structured output documentation, it is adequate but incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is only one parameter, target, and schema description coverage is 0% – the schema gives no meaning for target. The description says 'that apply to a resource' but never explains what the target string should be (ARM resource ID, resource name, scope URI, etc.). With a single undocumented parameter, the description should compensate but does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is precise about the resource and the operation: it returns active Azure RBAC role assignments that apply to a resource. It distinguishes the scope (resource, parent, RG, subscription, management groups) and explains what is returned. It does not explicitly differentiate from siblings such as get_access or identity_permissions, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when the tool is useful: when you need role assignments and inherited/direct access. It also clarifies that uncollected scopes are unknown, not zero. However, it does not name the alternative tools or say when to use one over the other, so usage guidance remains implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 16 tool updatesv0.3.8
    • First observedexport_map
    • First observedfind_resource
    • First observedfirewall_rules
    • First observedget_access
    • First observedget_node
    • First observedhybrid_connectivity
    • First observedidentity_permissions
    • First observedinfra_summary
    • First observedingress_paths
    • First observedlist_public_exposure
    • First observednsg_rules_for
    • First observedroute_for
    • First observedscan_infrastructure
    • First observedsearch_firewall_rules
    • First observedsearch_nsg_rules
    • First observedwho_has_access

TDQS

B3.4/5.0

Scored across 16 tools

Disambiguation4/5

Most tools have distinct scopes (find/get, scan/summary/export, per-resource vs estate-wide searches). A few pairs overlap conceptually—nsg_rules_for vs search_nsg_rules, firewall_rules vs search_firewall_rules, and who_has_access vs identity_permissions—but descriptions clarify per-resource vs global/bulk and RBAC vs managed-identity scopes.

Naming Consistency4/5

All names use lowercase snake_case consistently, which is the dominant pattern. Minor deviations exist: some are verb-first (scan_infrastructure, find_resource, get_node), others noun-first (infra_summary, firewall_rules, ingress_paths), and who_has_access is a question phrase, but the set remains readable and predictable.

Tool Count4/5

16 tools is slightly above the ideal 3–15 range but still well-scoped for a comprehensive Azure network graph and security analysis server. Each tool appears to cover a distinct analysis need, with no obvious filler.

Completeness4/5

The surface covers scanning, resource lookup, NSG/firewall rule analysis, routes, hybrid connectivity, RBAC/identity permissions, access verdicts, public exposure, and map export—strong coverage for read-only infrastructure analysis. Minor gaps like snapshot comparison or private DNS zone specifics are not fatal but leave some adjacent lifecycle concerns uncovered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    D
    quality
    D
    maintenance
    Enables read-only assessment of AWS environments by inventorying resources, running security and operational checks, and generating actionable reports with cost analysis. Designed for contractors with support for assume-role authentication using external IDs.
    10
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables scanning AWS accounts for cost optimization opportunities by reading resource configurations and pricing data, without making any modifications.
    22
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enterprise-grade Azure security assessment toolkit with multi-location scanning, IMDS exploitation, attack path analysis, and compliance reporting. Enables authorized penetration testing and compliance audits across all Azure regions.
    43
    11 npm
    MIT