devops-agent-networking
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@devops-agent-networkingTest connectivity to db.corp.internal port 5432"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
DevOps Agent - Network Diagnostics via Custom MCP
A deployable demo where AWS DevOps Agent autonomously troubleshoots VPC networking
problems (DNS, reachability, port blocks) by calling a custom MCP server that runs
dig / nc / ping / traceroute on an EC2 probe host via SSM - and returns
structured findings the agent reasons over and chains.
It has two complementary halves:
Live active probes (
resolve_dns,tcp_reachability,ping_host,traceroute_host) - authoritative for problems happening right now.Historical / forensic evidence (
flow_log_query) - queries VPC Flow Logs via Athena to answer "was traffic ACCEPTed or REJECTed over a past window, from whom, on which port, since when" - the only way to investigate an already-resolved or intermittent incident that the live probes are blind to.
A generic DevOps Agent Skill teaches the agent how to investigate - which half to reach for (live vs forensic) and how to read the verdicts.
Why this exists
DevOps Agent is read-only by design. Its permission guardrail blocks ssm:SendCommand
even if you grant it on the investigation role, so you cannot simply let the agent run
network probes. The AWS-sanctioned path is a custom MCP server: the guardrail does not
govern MCP tools. A tool-router Lambda holds the SSM permission and mediates a FIXED command
set, returning structured JSON.
Related MCP server: cloudwatch-mcp
Architecture

The agent reaches diagnostics through the custom MCP server (the read-only guardrail blocks
ssm:SendCommand on the agent role, but it does not govern MCP tools). The tool-router Lambda holds
the SSM permission and runs a FIXED command set on the single tagged probe host, parsing raw stdout
into structured JSON. For flow_log_query, the same Lambda runs a FIXED, partition-pruned,
aggregation-only Athena query over the VPC Flow Logs (Glue table on S3) inside a bytes-scanned-capped
WorkGroup, and returns a compact verdict - never raw rows.
Four stacks (all in one account / region, e.g. us-east-1):
Stack | Contents |
| VPC, probe host (tools), target host (nginx :80/:5432), Route53 private zone |
| VPC Flow Log (custom format) -> S3, Glue db/table with partition projection, Athena results bucket + WorkGroup (bytes-scanned cap) |
| API Gateway + API key + tool-router Lambda (SSM-scoped to the probe host; Athena/Glue/S3-scoped to the flow-logs surface) |
| Agent space, agent role (read-only), operator app role, monitor association |
Tools the agent gets (read-only, allow-listed)
Live probes (run a command on the probe host via SSM):
Tool | Runs | Returns |
|
| dns_status, resolved_ip, records, resolver, query_ms |
|
| verdict OPEN / CONNECTION_REFUSED / CONNECTION_TIMEOUT + remediation hint |
|
| reachable, loss_pct, rtt_avg_ms, verdict |
|
| per-hop list, last_responding_hop |
Historical / forensic (query VPC Flow Logs via Athena):
Tool | Runs | Returns |
| Fixed, partition-pruned Athena aggregation over VPC Flow Logs | verdict PERSISTENT_REJECT / INTERMITTENT / ALL_ACCEPT / NO_DATA, accept/reject counts, first/last_reject timestamps, top_peers, top_ports |
flow_log_query is flexible across dimensions - filter by any combination of:
ip+direction- pin an endpoint.direction:"to"(default) =ipis the destination (who connects to it);direction:"from"=ipis the source (where it connects to). Resolve a hostname to an IP withresolve_dnsfirst - flow logs record IPs, not names.port- destination port (omit for all ports; useful for port discovery).protocol-TCP/UDP/ICMP(omit for all).action-ACCEPT/REJECT/ALL.window_minutes- look-back window from now (default 60, max 180), orstart_time/end_time- an explicit incident window (ISO-8601 or epoch) to bracket exactly the range a client reported - this yields a clean verdict for the incident instead of blending it with surrounding healthy traffic. The result echoes the actualwindow_start/window_end.
At least one of ip / port / protocol is required so every query stays focused (and cheap).
The query shape is always GROUP BY ... LIMIT with a date-partition filter - the Lambda physically
cannot emit SELECT * or an unbounded scan, and the WorkGroup enforces a hard bytes-scanned cap.
Notes (what is real vs simulated)
Real: every probe is a genuine command executed on a real EC2 host against a real target; the packets, timeouts, and RTTs are real. The fault (
seed.sh) is a real security group rule removal - port 5432 is genuinely dropped, not mocked.Mediated & safe: the agent never gets a shell. Each tool runs a FIXED command vector; the only agent-controlled values are a validated hostname and port (injection is rejected before any SSM call). The Lambda is the only principal that can call
ssm:SendCommand, and onlyAWS-RunShellScripton the single tagged probe instance.Structured by construction: the agent never sees raw stdout - only the JSON the Lambda's per-command parsers produce (stable
finding_id, typed verdicts), so its reasoning is deterministic and composable.Flow logs are real and forensic:
flow_log_queryreads genuine VPC Flow Log records delivered to S3. They lag reality by ~10-20 minutes (aggregation + delivery), so a brand-new fault can readNO_DATAuntil records land - this is expected, and it is exactly why flow logs complement rather than replace the live probes. The demo runs 1-minute aggregation for a snappy loop; a production VPC typically runs 10-minute. Because the target has a public IP, flow logs also capture internet scanners hitting it - the tool'stop_peersbreakdown separates the legitimate private source from that public noise.
Prerequisites
Tested on macOS and Linux (the scripts/ are bash and use aws + jq; on Windows use WSL).
Tool | Version |
AWS CLI | v2 ( |
Node.js | >= 20 |
AWS CDK | v2 ( |
Python | 3.12 |
Docker | any recent (for |
AWS SAM CLI | >= 1.100 |
jq | any recent |
An AWS account + a named AWS CLI profile with credentials for it. Set the profile per run with
PROFILE=<your-profile>(the scripts assert the profile resolves to the expected account before mutating anything).Copy
.env.exampleto.envand set the target account/region:cp .env.example .env # then edit CDK_PROCESSING_ACCOUNT / CDK_PROCESSING_REGION
Cost
This deploys billable infrastructure. Running the demo for roughly an hour in us-east-1
is on the order of a few US$; leaving it running costs a few US$/day, dominated by the two
EC2 hosts and the NAT-free VPC. Rough on-demand estimate (verify with the AWS Pricing Calculator
for your region):
Resource | Rough cost |
2x EC2 |
|
VPC, subnets, Route53 private zone | negligible (no NAT gateway) |
API Gateway + Lambda | pay-per-use; negligible at demo volume |
S3 (flow logs) + Glue + Athena | pennies; Athena billed per TB scanned, bounded by a WorkGroup bytes-scanned cap |
VPC Flow Logs delivery | per-GB; negligible at demo volume |
Charges accrue until you tear down — run scripts/teardown.sh when finished (see below).
Run it
Every script requires PROFILE — the AWS CLI profile name for your account. Pass it as a
prefix on each command (or export PROFILE=<your-profile> once in your shell session):
# 1. Build + deploy all four stacks
PROFILE=<your-profile> scripts/deploy.sh
# 2. Register the MCP server with the agent space (API-key auth, all 5 tools allow-listed)
PROFILE=<your-profile> scripts/register.sh
# 3. Install the network-investigation Skill into the agent space (idempotent create/update).
# Or upload skills/network-connectivity-investigation/SKILL.md manually in the Operator App.
PROFILE=<your-profile> scripts/skill.sh
# 4. Inject the genuine fault (remove the 5432 ingress rule)
PROFILE=<your-profile> scripts/seed.sh
# 5. Preview the tool chain (incl. flow_log_query) + get the investigation prompt
PROFILE=<your-profile> scripts/trigger.sh
# 6. Restore the healthy baseline
PROFILE=<your-profile> scripts/reset.sh
# 7. Tear everything down (deletes the Skill, deregisters MCP server, then cdk destroy)
PROFILE=<your-profile> scripts/teardown.shAlternatively, export once and omit the prefix for the rest of the session:
export PROFILE=<your-profile>
scripts/deploy.sh
scripts/register.sh
# ...Every script verifies the profile resolves to the expected account before mutating anything. All scripts resolve the agent space id, MCP endpoint, API key, and resource names from CloudFormation outputs at runtime - nothing is hardcoded, so a teardown + redeploy (which produces new IDs) works without edits.
Staging the forensic (resolved-incident) scenario
# Seed the fault, generate 'remote client' traffic, reset - then wait for flow-log delivery.
# Leaves the environment HEALTHY with a bounded PAST window of REJECTs only flow_log_query
# can surface. Prints the incident window + an agent prompt.
PROFILE=<your-profile> scripts/scenario-forensic.sh [inject_minutes] [wait_minutes] # defaults 3, 11The Skill (investigation methodology)
skills/network-connectivity-investigation/SKILL.md is a generic (not demo-specific)
DevOps Agent Skill that teaches the agent how to investigate VPC connectivity problems:
Triage first - is the problem happening now (use the live probes) or already resolved / intermittent (use
flow_log_queryover the reported window, because the live probes are blind to a problem that isn't reproducing)?A live-probe decision tree (DNS -> ping -> tcp -> traceroute) with verdict interpretation (e.g.
CONNECTION_TIMEOUT=> suspect a security group/NACL; localize by comparing an allowed port).A flow-log playbook (direction, port discovery, protocol) and how to read each verdict.
It is methodology over the hard-bounded MCP tools - it steers tool choice, it does not hand
the agent raw SQL, so it adds investigative range without weakening the output guarantees.
Install it with scripts/skill.sh (Asset API) or upload the SKILL.md in the Operator App.
Demo beat 1 - live problem (ongoing)
With the fault seeded, ask the agent (Operator App chat):
A service cannot connect to its database at
db.corp.internalon port 5432. Determine whether the host is reachable, whether DNS resolves, and whether the database port is open. Confirm with the VPC flow logs whether traffic to that port is being rejected and since when. Identify the root cause and recommend a fix.
The agent chains:
resolve_dns (NOERROR -> 10.20.0.x) -> ping_host (ALIVE, 0% loss -> host is up) ->
tcp_reachability:80 (OPEN -> path works) -> tcp_reachability:5432 (CONNECTION_TIMEOUT) ->
flow_log_query to :5432 (PERSISTENT_REJECT if the window is clean, or INTERMITTENT if prior
baseline traffic blended in — either way first_reject timestamps the fault and top_peers
identifies the client IP) => root cause: a security group blocks tcp/5432, corroborated
by the flow logs; it cites the structured evidence and recommends restoring the ingress rule -
no shell. Note: the :80 flow-log query may show a reject from an internet scanner (public IP);
top_peers will confirm the probe has zero rejects on that port.
Demo beat 2 - resolved incident (historical, forensic)
Run scripts/scenario-forensic.sh (seeds, generates client traffic, resets, waits for delivery),
then ask the agent about the past window it printed:
A remote client reported they could not connect to
db.corp.internal(port 5432) a little while ago, roughly between<START>and<END>. It appears to work now. Investigate what happened, confirm whether it was a network issue, and tell me when it started and stopped.
This is the beat the live probes cannot solve: probing now returns OPEN (the problem isn't
reproducing). Guided by the Skill, the agent recognises the incident is historical and reaches
for flow_log_query - passing the reported start_time/end_time to scope exactly the window ->
PERSISTENT_REJECT with first_reject/last_reject bracketing the incident and top_peers = the
client's IP => it was a security-group block on tcp/5432 during that window, since restored.
Verified end-to-end: live tcp_reachability:5432 = OPEN while flow_log_query returns the past
REJECTs with correct timestamps.
Security & disclaimer
Demo posture: the target host has a public IP and
nginxon:80for a realistic reachability story, and the MCP endpoint is a public API Gateway URL guarded by an API key. This is fine for a short-lived demo but is not a hardened production posture — do not leave it running unattended, and treat the API key as a secret.Use at your own risk. You are responsible for any AWS resources you deploy and the charges they incur. Review the code and the Cost section before deploying, and tear down when finished.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/InitialXW/devops-agent-networking'
If you have feedback or need assistance with the MCP directory API, please join our Discord server