Skip to main content
Glama

VMware NSX

For a read-only check of this skill with your model and agent host, use the shared model-fit self-test in the marketplace root.

Author: Wei Zhou, VMware by Broadcom — zhouwei008@gmail.com This is a community-driven project by a VMware engineer, not an official VMware product. For official VMware developer tools see developer.broadcom.com.

English | 中文

VMware NSX networking management: segments, gateways, NAT, routing, IPAM — 33 MCP tools, domain-focused.

NSX Policy API skill for NSX-T 3.0+ and NSX 4.x.

License: MIT

MCP uses local stdio by default. Opt-in HTTPS opens the configured listener and requires TLS plus caller authentication; it is a network service, not a local-only mode. Credential examples create owner-only placeholder files without overwriting existing files; edit secrets locally.

Container examples build a local version-tagged image and run it with --pull=never, avoiding registry fallback. A local version tag is not an immutable image digest.

Companion Skills

Skill

Scope

Tools

Install

vmware-aiops ⭐ entry point

VM lifecycle, deployment, guest ops, clusters

49

uv tool install vmware-aiops

vmware-monitor

Read-only monitoring, alarms, events, VM info

27

uv tool install vmware-monitor

vmware-storage

Datastores, iSCSI, vSAN

11

uv tool install vmware-storage

vmware-vks

Tanzu Namespaces, TKC cluster lifecycle

20

uv tool install vmware-vks

vmware-nsx-security

DFW microsegmentation, security groups, Traceflow

21

uv tool install vmware-nsx-security

vmware-aria

Aria Ops metrics, alerts, capacity planning

28

uv tool install vmware-aria

vmware-avi

AVI/NSX ALB load balancing, AKO

28

uv tool install vmware-avi

vmware-harden

Compliance baselines, drift detection

6

uv tool install vmware-harden

Related MCP server: vmware-vks

Quick Install

# Via PyPI
uv tool install vmware-nsx-mgmt==1.15.2

# Or pip
pip install vmware-nsx-mgmt==1.15.2

Offline / Air-Gapped Install (from source)

This project uses the modern PEP 517 build system (hatchling), so there is no setup.py by design — that is expected, not a missing file. If you cloned the source and hit ERROR: File "setup.py" or "setup.cfg" not found ... editable mode currently requires a setuptools-based build, your pip is older than 21.3 and cannot do an editable (-e) install with a non-setuptools backend. Editable mode is a developer convenience, not needed to run the tool — do one of:

# From the source tree — a normal (non-editable) install builds a wheel:
pip install .              # NOT  pip install -e .

# ...or upgrade pip first, and editable works too:
pip install --upgrade pip && pip install -e .

For a truly air-gapped host, build the wheels on a connected machine and copy them over — the target then needs no network:

# On a connected machine, collect this package + its dependencies as wheels:
pip wheel . -w dist        # → dist/*.whl   (or: uv build, for just this package)

# Copy dist/ to the air-gapped host, then install offline:
pip install --no-index --find-links dist vmware-nsx-mgmt

Configuration

mkdir -p ~/.vmware-nsx
cp config.example.yaml ~/.vmware-nsx/config.yaml
# Edit with your NSX Manager credentials

(
  umask 077
  set -C  # Refuse existing files; edit an existing .env locally instead
  cat > ~/.vmware-nsx/.env <<'EOF'
VMWARE_NSX_NSX_PROD_PASSWORD=REPLACE_IN_LOCAL_EDITOR
EOF
)
# Before continuing, edit .env locally; never type live secrets into shell commands.

# Verify
vmware-nsx doctor

This writes placeholders only. Enter passwords or tokens using a local editor after creation; do not paste live credentials into terminal commands, chat or commits. If the file exists, the command refuses to overwrite it; edit the existing file after checking its permissions are 600.

What This Skill Does

Category

Tools

Count

Read / Write

Segments

list, get, create, update, delete

5

2R / 3W

Tier-0 Gateways

list, get, BGP neighbors, configure BGP

4

3R / 1W

Tier-1 Gateways

list, get, create, update, delete

5

2R / 3W

NAT

list, create, delete

3

1R / 2W

Static Routes

list, create, delete

3

1R / 2W

IP Pools

list, usage, create, delete

4

2R / 2W

Fabric Inventory

transport zones, transport nodes, edge clusters

3

3R / 0W

Health & Troubleshooting

alarms, transport node status, edge cluster status, manager status, port status, VM-to-segment

6

6R / 0W

Total: 33 tools (20 read-only + 13 write)

Common Workflows

Create an App Network (Segment + T1 Gateway + NAT)

  1. Create gateway: vmware-nsx gateway create-t1 app-t1 --edge-cluster edge-cluster-01 --tier0 tier0-gw

  2. Create segment: vmware-nsx segment create app-web-seg --name app-web-seg --tz <tz-overlay-path> --subnet 10.10.1.1/24

  3. Add SNAT: vmware-nsx nat create app-t1 --action SNAT --source 10.10.1.0/24 --translated 172.16.0.10

  4. Verify: vmware-nsx segment list and vmware-nsx nat list app-t1

Use --dry-run to preview any write command first.

Check Network Health

  1. Manager status: vmware-nsx health manager-status

  2. Transport nodes: vmware-nsx health transport-nodes

  3. Edge clusters: vmware-nsx health edge-clusters

  4. Alarms: vmware-nsx health alarms --severity HIGH (exact-match filter; query each severity separately)

Troubleshoot VM Connectivity

  1. Find VM's segment: vmware-nsx troubleshoot vm-segment <vm-display-name>

  2. Check port realized state: vmware-nsx troubleshoot port-status <segment-id> (all ports on the segment: attachment, realized bindings, transport nodes)

  3. Check routes: vmware-nsx gateway routes-t1 app-t1

  4. Check BGP: vmware-nsx gateway bgp-neighbors tier0-gw

MCP Tools (33 — 20 read, 13 write)

Category

Tools

Type

Segments

list_segments, get_segment, create_segment, update_segment, delete_segment

Read/Write

Tier-0 GW

list_tier0_gateways, get_tier0_gateway, get_bgp_neighbors, configure_tier0_bgp

Read/Write

Tier-1 GW

list_tier1_gateways, get_tier1_gateway, create_tier1_gateway, update_tier1_gateway, delete_tier1_gateway

Read/Write

NAT

list_nat_rules, create_nat_rule, delete_nat_rule

Read/Write

Static Routes

list_static_routes, create_static_route, delete_static_route

Read/Write

IP Pools

list_ip_pools, get_ip_pool_usage, create_ip_pool, delete_ip_pool

Read/Write

Fabric

list_transport_zones, list_transport_nodes, list_edge_clusters

Read

Health

list_nsx_alarms (per-severity, exact match), get_transport_node_status, get_edge_cluster_status, get_nsx_manager_status

Read

Troubleshoot

get_logical_port_status (realized state of all ports on a segment), get_segment_port_for_vm (lookup by VM display name)

Read

Full per-tool endpoints and methods: skills/vmware-nsx/references/capabilities.md.

CLI

# Segments
vmware-nsx segment list
vmware-nsx segment get app-web-seg
vmware-nsx segment create app-web-seg --name app-web-seg --tz <tz-overlay-path> --subnet 10.10.1.1/24
vmware-nsx segment delete app-web-seg

# Gateways
vmware-nsx gateway list-t0
vmware-nsx gateway list-t1
vmware-nsx gateway create-t1 app-t1 --edge-cluster edge-cluster-01 --tier0 tier0-gw
vmware-nsx gateway bgp-neighbors tier0-gw
vmware-nsx gateway routes-t1 app-t1

# NAT
vmware-nsx nat list app-t1
vmware-nsx nat create app-t1 --action SNAT --source 10.10.1.0/24 --translated 172.16.0.10
vmware-nsx nat delete-rule --tier1 app-t1 --rule-id rule-01

# Static Routes
vmware-nsx route list app-t1
vmware-nsx route create app-t1 --network 192.168.100.0/24 --next-hop 10.10.1.254

# IP Pools
vmware-nsx ippool list
vmware-nsx ippool create tep-pool
vmware-nsx ippool add-subnet tep-pool --start 192.168.100.10 --end 192.168.100.50 --cidr 192.168.100.0/24

# Health & Troubleshooting
vmware-nsx health alarms --severity HIGH   # exact match: LOW | MEDIUM | HIGH | CRITICAL
vmware-nsx health transport-nodes
vmware-nsx health manager-status
vmware-nsx troubleshoot vm-segment my-vm-01          # VM display name
vmware-nsx troubleshoot port-status app-web-seg      # segment ID

# Diagnostics
vmware-nsx doctor

MCP Server

After uv tool install vmware-nsx-mgmt==1.15.2, start the MCP server with one command (v1.5.15+):

# Recommended — single command, no network re-resolve
vmware-nsx mcp

# Or via Docker
docker compose up -d

Agent Configuration

Add to your AI agent's MCP config:

{
  "mcpServers": {
    "vmware-nsx": {
      "command": "vmware-nsx",
      "args": ["mcp"],
      "env": {
        "VMWARE_NSX_CONFIG": "~/.vmware-nsx/config.yaml"
      }
    }
  }
}
# Run without installing (requires PyPI access each launch)
uvx --from vmware-nsx-mgmt==1.15.2 vmware-nsx mcp

# Legacy entry point (still works, kept for backward compatibility)
vmware-nsx-mcp

Behind a corporate TLS proxy? uvx may fail with invalid peer certificate: UnknownIssuer. Use the recommended vmware-nsx mcp form above (no network needed), or set UV_NATIVE_TLS=true.

More agent config templates (Claude Code, Cursor, Goose, Continue, etc.) in examples/mcp-configs/.

Version Compatibility

NSX Version

Support

Notes

NSX 9.1

Full

Policy API supported. Note: VDS 7.0+ required (N-VDS removed in NSX 9).

NSX 9.0

Full

Policy API supported. Note: bare-metal agent / physical-server L2 overlay removed.

NSX 4.x

Full

Latest Policy API, all features

NSX-T 3.2

Full

All features work

NSX-T 3.1

Full

Minor route table format differences

NSX-T 3.0

Compatible

IP pool subnet API introduced here

NSX-T 2.5

Limited

Policy API incomplete; some tools may fail

NSX-V (6.x)

Not supported

Different API (SOAP-based)

VCF Compatibility

VCF Version

Bundled NSX

Support

VCF 9.1

NSX 9.1

Full

VCF 9.0

NSX 9.0

Full

VCF 5.x

NSX 4.x

Full

VCF 4.3-4.5

NSX-T 3.1-3.2

Full

Official Broadcom References

Safety

Feature

Description

Read-heavy

20/33 tools are read-only

Double confirmation

CLI write commands require two prompts

Dry-run mode

All write commands support --dry-run preview

MCP delete preview

The five MCP delete tools preview by default: without confirm=True they return blast_radius (what would be removed, blockers, unmeasured) and delete nothing. confirm=True is refused while a blocker remains or a read failed

Dependency checks

Segment delete refuses while ports are attached; Tier-1 delete refuses, deleting nothing, while segments, NAT rules, static routes, interfaces or VPN / DNS forwarder / LB services still depend on it (--dry-run runs the same check). On MCP, IP pool delete refuses while addresses are allocated — Policy ip-allocations, or NSX's pool_usage count, which also covers addresses Policy does not list (e.g. TEP pools) — and when pool_usage cannot be read. NAT rule and static route deletes have no blockers; their preview shows the rule's match or the route's network and next hops

Input validation

CIDR, IP, VLAN IDs, gateway existence validated

Audit logging

All operations logged to ~/.vmware-nsx/audit.log

No firewall ops

Cannot create/modify DFW rules or security groups

Credential safety

Passwords only from environment variables

Prompt injection defense

NSX object names sanitized before output

Troubleshooting

Problem

Cause & Fix

"Segment not found"

Policy API uses segment id, not display_name. Run segment list to get the exact ID.

NAT creation fails "gateway not found"

NAT requires a Tier-1 (or Tier-0) gateway. Verify with gateway list-t1. Gateway must have an edge cluster.

BGP neighbor stuck in Connect/Active

Peer unreachable, ASN mismatch, TCP 179 blocked, or MD5 password mismatch.

Transport node "degraded"

TEP unreachable (check MTU >= 1600), NTP sync issues, or host switch config mismatch.

"Password not found"

Variable naming: VMWARE_NSX_<TARGET_UPPER>_PASSWORD (hyphens to underscores). Check ~/.vmware-nsx/.env.

Connection timeout

Use vmware-nsx doctor --skip-auth to bypass auth checks on high-latency networks.

Remote access (HTTPS) and limiting tools

By default vmware-nsx mcp speaks stdio to one local client and offers every tool. Two options change that (vmware-policy ≥ 1.21.0).

Serve over HTTPS so clients on other machines can connect. Every caller needs a bearer token:

vmware-audit token create alice          # prints the token once; give it to alice
vmware-audit token list                  # names only
vmware-audit token revoke alice          # refused from its next request, no restart
vmware-nsx mcp --transport https --host 0.0.0.0 --port 8443 \
    --cert /etc/vmware-mcp/server.pem --key /etc/vmware-mcp/server-key.pem \
    --public-name mcp.example.com

Connect a client (Claude Code shown; any MCP client that supports streamable HTTP and custom headers works):

claude mcp add --transport http vmware-nsx https://mcp.example.com:8443/mcp \
    --header "Authorization: Bearer $VMWARE_MCP_TOKEN"
{
  "mcpServers": {
    "vmware-nsx": {
      "type": "http",
      "url": "https://mcp.example.com:8443/mcp",
      "headers": { "Authorization": "Bearer ${VMWARE_MCP_TOKEN}" }
    }
  }
}
  • The server will not start without a token, refuses Host/Origin values outside --public-name, and checks before it binds that unauthenticated requests get 401. Use a certificate your clients trust for those names.

  • Behind a TLS-terminating reverse proxy on the same machine use --transport http --host 127.0.0.1 --public-name mcp.example.com and pass the Authorization header through.

  • Behind a load balancer or gateway on another machine, keep --transport https (a self-signed certificate is fine), list in --public-name the host name the balancer sends as Host, and have it forward Authorization. Its health probe can use GET /healthz, which needs no token and returns only {"status": "ok"} (vmware-policy ≥ 1.23.0).

  • Send traceparent or X-Request-ID with each request to have it stored on the audit row; vmware-audit log --correlation-id ID then finds the calls behind one platform request.

  • The audit log records each caller as token:<name>. Calls run side by side, with or without a target: each target keeps up to VMWARE_MCP_POOL_SIZE sessions (default 2), and each session is a login on the target. A call that finds them all busy waits at most 300 s for one.

  • Everyone who can reach the endpoint acts with this server's account. Tokens identify callers; they grant nothing on the platform. Run one endpoint per privilege level.

  • Several people or roles on one endpoint: run vmware-audit roles enable once, then give each token a role (vmware-audit token create NAME --role reader, or a role in roles.yaml naming tools and targets; vmware-policy ≥ 1.24.0). A role limits what the token may call on this endpoint; it cannot grant more than the account has. See vmware-policy's README, "Roles for network callers".

Offer only read tools, plus the writes you choose:

vmware-nsx mcp --expose read --allow-write create_ip_pool
# or: VMWARE_NSX_MCP_EXPOSE=read VMWARE_NSX_MCP_ALLOW_WRITE=create_ip_pool vmware-nsx mcp

Tools not offered do not appear in the client's tool list. A bad value or an unknown write tool stops the server (exit 2). This limits what clients are offered; it is not authorization, so the account itself should be least-privilege.

Details: skills/vmware-nsx/references/setup-guide.md ("Serving MCP over HTTPS", "Limiting which tools are offered").

System proxy bypass

The NSX Manager REST client honors the operating system proxy bypass list for the configured origin. TLS verification still follows verify_ssl, and CA environment settings such as SSL_CERT_FILE remain active. Other origins retain their normal proxy routing.

License

MIT

Available Tools

33 tools
configure_tier0_bgpA

[WRITE] Configure BGP settings on a Tier-0 gateway's locale-service.

Use get_tier0_gateway first to confirm the tier0_id. Sets BGP settings only (local AS, ECMP, inter-SR iBGP); neighbor creation is a separate Policy API object not exposed here, so peering will not come up from this call alone. Returns the updated BGP config dict, else {"error", "hint"}. Then check get_bgp_neighbors for session state.

Inputs: tier0_id (required), local_as_num (required), ecmp, target, +3 more.

create_ip_poolA

[WRITE] Create an IP address pool with one static subnet and allocation range.

IP pools supply addresses to NSX consumers such as tunnel endpoints. Run list_ip_pools first to avoid overlapping ranges; start_ip and end_ip must both fall inside cidr. The same pool_id overwrites (PUT). Returns {"created", "pool_id", "subnets_created", "subnets_failed"}. If the subnet failed it also has "error": the pool itself WAS created and needs cleaning up (the error says how). Other failures return {"error", "hint"}. Verify with get_ip_pool_usage; delete_ip_pool is the inverse.

Inputs: cidr (required), end_ip (required), pool_id (required), start_ip (required), +3 more.

create_nat_ruleA

[WRITE] Create a NAT rule on a Tier-1 gateway's USER NAT section.

Run list_tier1_gateways for tier1_id and list_nat_rules to avoid an id clash — the same rule_id overwrites. The gateway must have an edge cluster (see create_tier1_gateway) or NAT cannot be realized, and TIER1_NAT advertisement must be set via update_tier1_gateway for the translated address to be reachable from outside. Returns the created rule dict, else {"error", "hint"}. Then confirm with list_nat_rules; delete_nat_rule is the inverse.

Inputs: rule_id (required), tier1_id (required), action, target, +3 more.

create_segmentA

[WRITE] Create an overlay or VLAN-backed NSX network segment.

Run list_transport_zones first for transport_zone_path; it decides whether subnet or vlan_ids applies — the wrong one is rejected. The same segment_id overwrites (PUT). Returns the created segment dict, else {"error", "hint"}. A segment with no gateway is isolated: link it with create_tier1_gateway, then verify with get_segment.

Inputs: segment_id (required), display_name (required), transport_zone_path (required), subnet, +2 more.

create_static_routeA

[WRITE] Create a static route on a Tier-0 or Tier-1 gateway via the Policy API.

Use this for destinations not covered by connected or advertised routes, e.g. a VPN or external subnet. Run list_static_routes first to avoid an id clash — the same route_id overwrites (PUT). For the Tier-0 to advertise a Tier-1's static route upstream, the gateway needs TIER1_STATIC_ROUTES advertisement, set via update_tier1_gateway. Returns the created route dict, else {"error", "hint"}. Then confirm with list_static_routes; delete_static_route is the inverse.

Inputs: network (required), next_hop (required), route_id (required), tier1_id (required), +2 more.

create_tier1_gatewayA

[WRITE] Create a Tier-1 gateway to route segments, optionally uplinked to a Tier-0.

Use this before create_segment when the segment needs routing; get tier0_path from list_tier0_gateways and edge_cluster_path from list_edge_clusters first. Without route_advertisement, connected subnets stay unreachable from outside until it is set here or via update_tier1_gateway. The same tier1_id overwrites (PUT). Returns the created gateway dict, else {"error", "hint"}; verify with get_tier1_gateway.

Inputs: tier1_id (required), display_name (required), target, tier0_path, +2 more.

delete_ip_poolA
Destructive

[WRITE] Permanently delete an IP address pool; refuses while IPs are allocated.

Irreversible: consumers such as transport endpoints can no longer allocate. Without confirm=True this only previews: it returns blast_radius (the pool's name, pool_usage, allocation_count, realized_allocation_count and allocated_ips, blockers, unmeasured) and deletes nothing. Show that to the user and get their decision. Do not set confirm=True on your own because the user asked to delete earlier: they have not seen the blast radius yet. confirm=True refuses while any IP is still allocated — in Policy ip-allocations or in NSX's pool_usage count, which also covers TEP addresses — or when either count could not be read. Returns {"action": "preview" | "deleted", "blast_radius": ...}, else {"error", "hint", "blast_radius"?}.

Inputs: pool_id (required), target, confirm.

delete_nat_ruleA
Destructive

[WRITE] Permanently delete a NAT rule from a Tier-1 gateway's USER NAT section.

Irreversible: traffic matched by the rule stops being translated immediately, which can break inbound (DNAT) or outbound (SNAT) connectivity. Without confirm=True this only previews: it returns blast_radius (the gateway, the rule's action, source/destination match and translation, enabled flag, blockers, unmeasured) and deletes nothing. Show that to the user and get their decision. Do not set confirm=True on your own because the user asked to delete earlier: they have not seen the blast radius yet. confirm=True refuses when the rule could not be read, and a rule_id not on that gateway is an error. Returns {"action": "preview" | "deleted", "blast_radius": ...}, else {"error", "hint", "blast_radius"?}.

Inputs: rule_id (required), tier1_id (required), target, confirm.

delete_segmentA
Destructive

[WRITE] Delete a network segment; refuses while any port is attached.

Irreversible. Without confirm=True this only previews: it returns blast_radius (the segment's name, gateway, subnets, port_count and port_ids, blockers, unmeasured) and deletes nothing. Show that to the user and get their decision. Do not set confirm=True on your own because the user asked to delete earlier: they have not seen the blast radius yet.

confirm=True re-measures, then refuses, deleting nothing, while any port (a VM vNIC or router interface) is attached — it never disconnects them for you — or when the ports could not be read. Returns {"action": "preview" | "deleted", "blast_radius": ...}, else {"error", "hint", "blast_radius"?}.

Inputs: segment_id (required), target, confirm.

delete_static_routeA
Destructive

[WRITE] Permanently delete a static route from a Tier-0 or Tier-1 gateway.

Irreversible: traffic to the route's destination CIDR immediately falls back to remaining routes or is dropped. Without confirm=True this only previews: it returns blast_radius (the gateway, the route's network and next hops, blockers, unmeasured) and deletes nothing. Show that to the user and get their decision. Do not set confirm=True on your own because the user asked to delete earlier: they have not seen the blast radius yet. gateway_type must match where the route lives; a route_id not on that gateway is an error, and confirm=True refuses when the routes could not be read. Returns {"action": "preview" | "deleted", "blast_radius": ...}, else {"error", "hint", "blast_radius"?}.

Inputs: route_id (required), tier1_id (required), target, confirm, +1 more.

delete_tier1_gatewayA
Destructive

[WRITE] Delete a Tier-1 gateway; refuses while anything still depends on it.

Irreversible. Without confirm=True this only previews: it returns blast_radius (name, tier0_path, the "default" locale-service and edge cluster the delete removes, dependents by kind, blockers, unmeasured) and deletes nothing. Show that to the user and get their decision. Do not set confirm=True on your own because the user asked to delete earlier: they have not seen the blast radius yet.

confirm=True re-measures (read-only) and refuses, deleting nothing, while any remain: attached segments or Tier-1-scoped segments, NAT rules, static routes, service interfaces, extra locale-services, IPsec/L2 VPN services, a DNS forwarder, or a load balancer service attached to it — or when any of them could not be read. It never removes them for you. When clear, deletes the "default" locale-service, then the gateway. Returns {"action": "preview" | "deleted", "blast_radius": ...}, else {"error", "hint", "blast_radius"?}.

Inputs: tier1_id (required), target, confirm.

get_bgp_neighborsA
Read-onlyIdempotent

[READ] Get BGP configuration and neighbor status for a Tier-0 gateway.

Use this to verify dynamic routing after configure_tier0_bgp, or when troubleshooting north-south connectivity. Returns one dict (not the list envelope): tier0_id, locale-service info, BGP config (local AS, enabled, ECMP), neighbors (peer IP, remote ASN, timers) and realized session status (connection_state, in/out prefix counts). Only the gateway's FIRST locale-service is read; a gateway with none returns a hint, not an error.

If sessions are down, check get_edge_cluster_status — BGP runs on the edge members. Static routes are listed separately by list_static_routes.

Inputs: tier0_id (required), target.

get_edge_cluster_statusA
Read-onlyIdempotent

[READ] Check status of an edge cluster (member health, overall status).

Use this after list_edge_clusters when north-south traffic, NAT or BGP looks broken — Tier-0/Tier-1 stateful services run on these members. Returns one dict (not the list envelope): cluster_id, edge_cluster_status, member_count and members (transport_node_id, transport_node_name, status). Member status only — why a member is degraded comes from get_transport_node_status.

Inputs: cluster_id (required), target.

get_ip_pool_usageA
Read-onlyIdempotent

[READ] Get current IP allocations for one IP address pool.

Use this after list_ip_pools to see how much of a pool is consumed — e.g. diagnosing TEP address exhaustion, or before delete_ip_pool, which cannot proceed while allocations remain. Returns a single dict (not the list envelope): pool_id, allocation_count and allocations (id, display_name, allocation_ip). An empty allocations list means the pool is unused, not that the query failed. On failure returns {"error", "hint"}.

Inputs: pool_id (required), target.

get_logical_port_statusA
Read-onlyIdempotent

[READ] Check realized state of all ports on a segment (first 50 ports).

Use this after get_segment_port_for_vm has told you which segment a VM sits on, or before delete_segment to see whether ports are still attached. Returns per-port admin_state, attachment (type/id) and realized state: attached, realized_bindings_count, transport_node_ids. NSX does not expose a single UP/DOWN flag per segment port — an attached port with realized bindings on at least one transport node is healthy. Only the first 50 ports are returned.

If bindings are missing everywhere, check get_transport_node_status.

Inputs: segment_id (required), target.

get_nsx_manager_statusA
Read-onlyIdempotent

[READ] Get NSX Manager cluster status (node health, control/management plane).

Start any NSX health check here: if the manager cluster is degraded, every other reading is suspect. Returns one dict (not the list envelope): cluster_id, overall_status, control_cluster_status, mgmt_cluster_status, online_node_count and nodes. Only online nodes are listed, so a node missing from nodes is down rather than absent. Then list_nsx_alarms for what is actually firing.

Inputs: target.

get_segmentA
Read-onlyIdempotent

[READ] Get full details for one network segment, including its attached ports.

Use after list_segments to inspect one segment. Returns one dict (not the list envelope): id, display_name, type, admin_state, subnets, transport_zone_path, connectivity_path (linked gateway), vlan_ids, port_count, and the first 50 ports only. A segment with attached ports cannot be deleted — check port_count before calling delete_segment. For per-port realized state use get_logical_port_status; to change the segment use update_segment.

Inputs: segment_id (required), target.

get_segment_port_for_vmA
Read-onlyIdempotent

[READ] Find which segment(s) a VM is attached to via its VIF attachments.

Start here for "why can this VM not reach the network?" — it is the only tool mapping a VM name onto NSX topology. Looks the VM up in the fabric inventory, fetches its VIFs, and matches segment ports by lport_attachment_id. Returns one dict (not the list envelope): VM info (external_id, host, power state) and matched_ports (segment id/name, port id/name). Matching is on exact display name, and empty matched_ports means no VIF is attached, not that the VM is missing.

Then get_logical_port_status on the segment it names. VM power and placement are not managed here — use vmware-aiops.

Inputs: vm_display_name (required), target.

get_tier0_gatewayA
Read-onlyIdempotent

[READ] Get configuration details for one Tier-0 gateway (north-south edge router).

Use after list_tier0_gateways to inspect HA configuration, or to build the tier0_path ("/infra/tier-0s/") that create_tier1_gateway needs. For BGP peering state use get_bgp_neighbors instead. Returns one dict (not the list envelope): id, display_name, ha_mode, failover_mode, transit_subnets, internal_transit_subnets, rd_admin_field. Static config only — it does not say whether the gateway is currently forwarding.

Inputs: tier0_id (required), target.

get_tier1_gatewayA
Read-onlyIdempotent

[READ] Get detailed info for one Tier-1 gateway.

Use after list_tier1_gateways, and always before update_tier1_gateway — update is a PATCH, so you need the current values to know what you are changing. Returns a single detail dict (not the list envelope): id, display_name, tier0_path, failover_mode, route_advertisement_types, type. Attached segments are not listed here — use list_segments for those.

Inputs: tier1_id (required), target.

get_transport_node_statusA
Read-onlyIdempotent

[READ] Get realized runtime status of one transport node (ESXi host or Edge node).

Use after list_transport_nodes when a node looks degraded or overlay tunnels are suspect; for cluster-wide edge health use get_edge_cluster_status instead. Returns one dict (not the list envelope): node_id, status (UP, DEGRADED, DOWN, UNKNOWN), control_connection_status, mgmt_connection_status, tunnel_status (up/down/degraded counts, BFD counters) and pnic_status. Point-in-time only — no history.

If tunnels are down on one segment only, follow up with get_logical_port_status rather than blaming the node.

Inputs: node_id (required), target.

list_edge_clustersA
Read-onlyIdempotent

[READ] List all edge clusters with member count and deployment type.

Returns the result envelope; check truncated before calling it complete. Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this first to resolve a cluster_id, then get_edge_cluster_status for member health. The id is also what create_tier1_gateway's edge_cluster_path is built from — a Tier-1 without an edge cluster cannot run NAT.

Inputs: limit, offset, target.

list_ip_poolsA
Read-onlyIdempotent

[READ] List all IP address pools with subnets and usage summary.

Returns the result envelope; check truncated before calling it complete. Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this first to resolve a pool_id, then get_ip_pool_usage for the actual allocations — the summary here does not tell you which addresses are taken. Run it before create_ip_pool to avoid overlapping ranges.

Inputs: limit, offset, target.

list_nat_rulesA
Read-onlyIdempotent

[READ] List NAT rules on a Tier-1 gateway (USER section).

Returns the result envelope; check truncated before calling it complete. Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Get tier1_id from list_tier1_gateways first. Use this before create_nat_rule to avoid an id clash, and before delete_nat_rule to confirm what a rule does. Only the USER section is listed — NSX-internal NAT is not shown.

Inputs: tier1_id (required), limit, offset, target.

list_nsx_alarmsA
Read-onlyIdempotent

[READ] Get active NSX alarms at one severity, with feature, description, and entity.

Returns the result envelope; check truncated before calling it complete. Note: the NSX severity filter is an EXACT match — "MEDIUM" returns only MEDIUM alarms, not MEDIUM-and-above, so call it once per severity to build a full picture.

Page it: limit is the page size (1-1000, 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole set, so it stays true on the last page of a walk. Unlike the other list tools this one defaults to the full 1000, because a health sweep that silently showed the first fifty alarms would be worse than a long one.

Start a health check at get_nsx_manager_status, then come here, then drill into the entity the alarm names with get_transport_node_status or get_edge_cluster_status.

Inputs: limit, offset, target, severity.

list_segmentsA
Read-onlyIdempotent

[READ] List all NSX network segments with type, subnet, admin state, and port count.

Returns the result envelope: rows under items, plus returned, limit, total (the collection's result_count, null when the API omits it), truncated and hint. Check truncated before calling this the complete set — when true, more rows exist. Every list tool here returns that shape.

Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this first to resolve a segment_id, then get_segment for its ports and linked gateway, or get_logical_port_status for realized state. Distributed firewall rules are not here — use vmware-nsx-security.

Inputs: limit, offset, target.

list_static_routesA
Read-onlyIdempotent

[READ] List static routes on a Tier-0 or Tier-1 gateway.

Returns the result envelope; check truncated before calling it complete. Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this before create_static_route to avoid an id clash, and before delete_static_route to confirm the destination and next hops. gateway_type must match where the route actually lives — querying the wrong tier returns an empty list, not an error. BGP-learned routes are not here; use get_bgp_neighbors.

Inputs: tier1_id (required), limit, offset, target, +1 more.

list_tier0_gatewaysA
Read-onlyIdempotent

[READ] List all Tier-0 gateways with HA mode and transit subnets.

Returns the result envelope; check truncated before calling it complete. Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this first to resolve a tier0_id, then get_tier0_gateway for HA detail and the tier0_path that create_tier1_gateway needs, or get_bgp_neighbors for peering state. Tier-0s are not created by this skill — only Tier-1s are.

Inputs: limit, offset, target.

list_tier1_gatewaysA
Read-onlyIdempotent

[READ] List all Tier-1 gateways with linked Tier-0 path and route advertisement.

Returns the result envelope; check truncated before calling it complete. Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this first to resolve a tier1_id — create_nat_rule, create_static_route, list_nat_rules and update_tier1_gateway all take one. A row with an empty tier0_path is standalone and cannot reach north-south. Then get_tier1_gateway for detail.

Inputs: limit, offset, target.

list_transport_nodesA
Read-onlyIdempotent

[READ] List all transport nodes (ESXi hosts and Edge nodes) with type and status.

Returns the result envelope; check truncated before calling it complete. Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this first to resolve a node_id, then get_transport_node_status for that node's tunnels, controller connectivity and pNICs — the summary status here does not explain why a node is degraded.

Inputs: limit, offset, target.

list_transport_zonesA
Read-onlyIdempotent

[READ] List all NSX transport zones — the overlay/VLAN boundaries segments attach to.

Page it: limit is the page size (1-1000, default 50; 0 or negative is rejected), offset is how many rows to skip, and the response carries next_offset — pass that back as offset and stop when it is null. Do not loop on truncated: that says this page is not the whole collection, so it stays true on the last page of a walk.

Use this first when building a segment: create_segment requires a transport_zone_path of "/infra/sites/default/enforcement-points/default/transport-zones/" built from the id returned here. Returns the result envelope; each row has id, display_name and transport_type (OVERLAY_STANDARD, VLAN_BACKED, …). A VLAN-backed zone needs create_segment's vlan_ids, an overlay zone needs its subnet — passing the wrong one is rejected.

Inputs: limit, offset, target.

update_segmentA

[WRITE] Update an existing network segment (partial update via PATCH).

Only the fields you pass change. Use get_segment first, and prefer this over create_segment for an existing segment: create is a PUT and overwrites everything. Changing subnet re-addresses the gateway and can drop traffic for attached VMs, so check port_count first. Returns the updated segment dict, else {"error", "hint"}.

Inputs: segment_id (required), subnet, target, display_name.

update_tier1_gatewayA

[WRITE] Partially update an existing Tier-1 gateway via PATCH.

Only the fields you pass change. Use get_tier1_gateway first — route_advertisement is sent as a whole list, so include every type you want kept. Prefer this over create_tier1_gateway for an existing gateway: create is a PUT and overwrites everything. Re-applying identical values is harmless. Returns the updated gateway dict, else {"error", "hint"}.

Inputs: tier1_id (required), target, tier0_path, display_name, +1 more.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4.4/5.0

    Scored across 33 tools

    Disambiguation5/5

    Every tool pairs a distinct NSX resource (segment, Tier-1 gateway, NAT rule, static route, IP pool, transport node, edge cluster) with a distinct action (list/get/create/update/delete/status). Even the two port-related tools are cleanly separated: get_segment_port_for_vm maps a VM to a segment, while get_logical_port_status reports realized port state on a segment.

    Naming Consistency5/5

    All tool names are lowercase snake_case following a consistent verb_noun pattern: list_* for collection reads, get_* for detail/status reads, and create_*/update_*/delete_* for mutations. The only slightly unusual name, configure_tier0_bgp, still follows the verb_noun convention and is unambiguous.

    Tool Count3/5

    At 33 tools, this is well above the ideal 3-15 range and past the 16-25 'heavy' band. However, the NSX domain is broad and every tool maps to a real resource/action with no obvious duplicates, so the large surface feels heavy rather than bloated.

    Completeness4/5

    Core lifecycles are covered for segments, Tier-1 gateways, NAT rules, static routes, and IP pools, with health/status reads and VM-to-segment lookup filling out the domain. Minor gaps exist: BGP neighbor creation is not exposed, NAT rules and static routes have no update operation (requiring delete+recreate), and Tier-0 gateway creation is intentionally out of scope.

    Maintenance

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers