AWS Infrastructure Operations MCP
This server provides read-only diagnostic tools for a single AWS EC2 instance (web01) and the nginx service. It exposes six MCP tools that return live AWS evidence without granting general AWS or shell access.
get_instance_health: Check EC2 state and AWS system/instance status checks.get_instance_metrics: Fetch CPU, status-check, and network metrics from CloudWatch for a configurable lookback (5–1440 minutes, default 60).get_recent_errors: Search two fixed CloudWatch log groups for recent errors (up to 50 results, 5–1440 minute lookback).get_recent_changes: Retrieve CloudTrail events forweb01within a 1–168 hour lookback, limited to approved event names.get_service_status: Check active state, sub-state, and boot-enabled state ofnginxvia a fixed SSM document.get_service_journal: Retrieve a boundednginxsystemd journal (5–120 minute lookback, up to 100 entries) via a fixed SSM document.
All tools are read‑only; no restart, stop, deploy, or remediation actions are available. The server works exclusively with web01 and nginx, and all parameters are allowlisted. It requires a specific restricted IAM role (aws-infra-ops-mcp-lab-runtime) and will not run under broader credentials.
Provides tools to check nginx service status (active state, sub-state, boot-enabled) and retrieve recent error-related events from nginx log groups.
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., "@AWS Infrastructure Operations MCPCheck web01's EC2 health and recent nginx errors."
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.
AWS Infrastructure Operations MCP
A local, read-only MCP server that allows an AI client such as Codex to investigate an AWS EC2 workload using controlled, live evidence.
The server can inspect EC2 health, CloudWatch metrics, CloudWatch logs, nginx service state, the nginx system journal, and recent CloudTrail activity. It does not expose a general-purpose shell or any remediation capabilities.
What this project demonstrates
This project combines:
Model Context Protocol (MCP)
Python and FastMCP
AWS SDK for Python (Boto3)
Amazon EC2
Amazon CloudWatch Metrics
Amazon CloudWatch Logs Insights
AWS Systems Manager
AWS CloudTrail
AWS IAM and STS
Terraform
Least-privilege infrastructure diagnostics
The current implementation supports one approved lab instance named web01 and one approved service named nginx.
Related MCP server: masaro-infra-mcp
Architecture
flowchart LR
User["Engineer"] --> Codex["Codex MCP host"]
Codex --> MCP["Local Python MCP server"]
MCP --> Guard["AWS runtime identity guard"]
Guard --> STS["AWS STS"]
MCP --> EC2["Amazon EC2"]
MCP --> Metrics["CloudWatch Metrics"]
MCP --> Logs["CloudWatch Logs"]
MCP --> SSM["AWS Systems Manager"]
MCP --> Trail["AWS CloudTrail"]
SSM --> Web01["EC2: web01"]Codex starts the MCP server as a local process and communicates with it over standard input and output.
The MCP server:
Validates its AWS account and assumed role.
Validates the requested instance, service, time range, and result limit.
Calls only approved AWS APIs.
Returns a limited structured result with its data source.
Does not perform remediation.
MCP tools
The server exposes six live AWS-backed tools.
Tool | Purpose | Data source |
| Returns EC2 state and AWS system and instance status checks |
|
| Returns fixed EC2 CPU, status-check, and network metrics |
|
| Searches approved CloudWatch log groups for recent errors |
|
| Returns bounded CloudTrail activity associated with the instance |
|
| Returns the current nginx systemd state through a fixed SSM document |
|
| Returns a bounded nginx system journal through a fixed SSM document |
|
get_instance_health
instance_name: strCurrent restrictions:
instance_namemust beweb01.Callers cannot supply an EC2 instance ID.
Instance resolution requires the approved EC2 name and access tags.
The response includes:
Instance ID
AWS Region
Availability Zone
Private IP address
EC2 state
System status
Instance status
Check timestamp
get_instance_metrics
instance_name: str
minutes: int = 60Current restrictions:
instance_namemust beweb01.minutesmust be between 5 and 1,440.The caller cannot supply a metric namespace, dimension, statistic, period, or CloudWatch query.
The tool retrieves a fixed set of AWS/EC2 metrics:
CPUUtilizationStatusCheckFailedStatusCheckFailed_InstanceStatusCheckFailed_SystemNetworkInNetworkOut
Missing datapoints are returned as null rather than being represented as zero.
get_recent_errors
instance_name: str
maximum_results: int = 10
minutes: int = 60Current restrictions:
instance_namemust beweb01.maximum_resultsmust be between 1 and 50.minutesmust be between 5 and 1,440.Callers cannot provide Logs Insights query text or log-group names.
The server queries only:
/aws/mcp-lab/web01/system
/aws/mcp-lab/web01/nginxAn empty result means that no matching events were returned within the requested window. It does not prove that the application is reachable or healthy.
get_recent_changes
instance_name: str
hours: int = 24
maximum_results: int = 25Allowed lookback values:
1, 6, 12, 24, 48, 72, 168 hoursAllowed result limits:
10, 25, 50The tool searches a fixed server-side allowlist of relevant EC2 and Systems Manager events. It then verifies that each event explicitly references the approved instance ID.
Returned event information is deliberately limited to:
Event time
Event name
Event source
Compact actor attribution
CloudTrail read-only indicator
Instance-matching method
The tool does not return raw CloudTrail JSON, credentials, request headers, source IP addresses, user-agent strings, or complete session context.
CloudTrail Event History is eventually consistent. Very recent API activity may take several minutes to appear.
get_service_status
instance_name: str
service_name: strCurrent restrictions:
instance_namemust beweb01.service_namemust benginx.The caller cannot provide a command, document name, path, instance ID, or shell argument.
The tool invokes only the Terraform-managed SSM document:
mcp-lab-get-nginx-statusThe document runs a fixed set of read-only systemctl checks and returns:
Active state
Sub-state
Whether nginx is enabled at boot
Command status
Check timestamp
get_service_journal
instance_name: str
service_name: str
minutes: int = 60
maximum_results: int = 50Allowed lookback values:
5, 10, 15, 30, 60, 120 minutesAllowed result limits:
10, 25, 50, 100The tool invokes only:
mcp-lab-get-nginx-journalThe document fixes the systemd unit to nginx and executes a bounded, read-only journal query.
The SSM document internally uses the aws:runShellScript document plugin to execute its fixed command. This is not the same as allowing the MCP runtime to invoke the unrestricted AWS-managed AWS-RunShellScript document.
Security boundaries
The project follows a defence-in-depth model.
Dedicated runtime role
The MCP server uses a dedicated role:
aws-infra-ops-mcp-lab-runtimeThis is separate from:
The Terraform administrator or source identity
The EC2 instance profile
The user’s interactive AWS identity
The runtime role receives only the permissions required by the approved diagnostic tools.
Fail-closed identity guard
Before an AWS-backed tool creates its service client, the server calls AWS STS and validates:
The expected AWS account
The exact assumed-role name
The expected STS assumed-role ARN structure
Required environment variables:
MCP_EXPECTED_AWS_ACCOUNT_ID
MCP_EXPECTED_AWS_ROLE_NAMEThe server accepts an identity shaped like:
arn:aws:sts::<AWS_ACCOUNT_ID>:assumed-role/aws-infra-ops-mcp-lab-runtime/<session-name>It rejects:
Administrator roles
Unexpected assumed roles
IAM users
The AWS account root identity
Incorrect AWS accounts
Missing or malformed identity configuration
Incomplete STS responses
Only successful identity validation is cached for the lifetime of the MCP process.
Approved targets
The current server supports only:
Instance: web01
Service: nginxThe instance must have these tags:
Tag | Value |
|
|
|
|
The model cannot provide arbitrary instance IDs, AWS queries, commands, files, services, document names, log groups, or metric names.
No remediation
The server does not provide tools to:
Start, stop, reboot, or terminate EC2 instances
Restart services
Change security groups or routes
Modify IAM
Execute arbitrary shell commands
Create or delete AWS resources
Change application configuration
Run Terraform
Open interactive SSM sessions
Any recovery action remains a separate, human-controlled activity.
Repository structure
aws-infra-ops-mcp/
├── aws_infra_ops_mcp/
│ ├── tools/
│ │ ├── instance_health.py
│ │ ├── instance_metrics.py
│ │ ├── recent_changes.py
│ │ ├── recent_errors.py
│ │ ├── service_journal.py
│ │ └── service_status.py
│ ├── __init__.py
│ ├── app.py
│ ├── aws.py
│ ├── policy.py
│ └── runtime_identity.py
├── infrastructure/
│ ├── modules/
│ ├── main.tf
│ ├── outputs.tf
│ ├── providers.tf
│ ├── terraform.tfvars.example
│ ├── variables.tf
│ └── versions.tf
├── .gitignore
├── pyproject.toml
├── README.md
└── server.pyPrerequisites
Python 3.11 or newer
Terraform 1.6 or newer
AWS CLI
AWS Session Manager plugin
Codex with local MCP support
An AWS source identity that can deploy the Terraform configuration
An AWS Region configured
The example infrastructure defaults to:
ap-southeast-1Local installation
On Linux, macOS, or WSL:
cd <PROJECT_DIR>
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e .On Windows PowerShell:
Set-Location <PROJECT_DIR>
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e .AWS profiles
Use separate profiles for deployment and diagnostics.
Deployment profile
The source or administrator profile is used by Terraform:
defaultMCP runtime profile
The MCP server uses:
mcp-lab-runtimeExample AWS configuration:
[profile mcp-lab-runtime]
role_arn = arn:aws:iam::<AWS_ACCOUNT_ID>:role/aws-infra-ops-mcp-lab-runtime
source_profile = default
role_session_name = aws-infra-ops-mcp
duration_seconds = 3600
region = ap-southeast-1Do not run Terraform using mcp-lab-runtime. Its restricted permissions are intentional.
Terraform deployment
Copy the example variables file:
cp infrastructure/terraform.tfvars.example infrastructure/terraform.tfvarsUpdate the values for your AWS account and environment.
Deploy using the source or administrator profile:
export AWS_PROFILE=default
terraform -chdir=infrastructure init
terraform -chdir=infrastructure fmt -check -recursive
terraform -chdir=infrastructure validate
terraform -chdir=infrastructure plan -out=tfplan
terraform -chdir=infrastructure apply tfplanTerraform creates the lab infrastructure, including:
Networking
EC2 instance
EC2 instance profile
Systems Manager connectivity
CloudWatch log groups
CloudWatch Agent configuration
Custom SSM diagnostic documents
Restricted MCP runtime role
Read-only diagnostic IAM policy
Terraform uses local state in this example. State files and variable files are excluded from Git and must be stored securely.
Running the MCP server
Set the runtime profile and identity guard values:
export AWS_PROFILE=mcp-lab-runtime
export AWS_REGION=ap-southeast-1
export AWS_DEFAULT_REGION=ap-southeast-1
export AWS_SDK_LOAD_CONFIG=1
export MCP_EXPECTED_AWS_ACCOUNT_ID=<AWS_ACCOUNT_ID>
export MCP_EXPECTED_AWS_ROLE_NAME=aws-infra-ops-mcp-lab-runtimeStart the server:
aws-infra-ops-mcpFor a local stdio server, it may appear to wait without displaying a prompt. That is expected because it is waiting for MCP messages on standard input.
Connecting Codex
Add the server to your Codex configuration:
[mcp_servers.aws-infra-ops-lab]
command = "/absolute/path/to/aws-infra-ops-mcp/.venv/bin/python"
args = ["/absolute/path/to/aws-infra-ops-mcp/server.py"]
cwd = "/absolute/path/to/aws-infra-ops-mcp"
[mcp_servers.aws-infra-ops-lab.env]
AWS_PROFILE = "mcp-lab-runtime"
AWS_REGION = "ap-southeast-1"
AWS_DEFAULT_REGION = "ap-southeast-1"
AWS_SDK_LOAD_CONFIG = "1"
MCP_EXPECTED_AWS_ACCOUNT_ID = "<AWS_ACCOUNT_ID>"
MCP_EXPECTED_AWS_ROLE_NAME = "aws-infra-ops-mcp-lab-runtime"Restart Codex after changing its MCP configuration.
Use /mcp to confirm the server and its six tools are available.
Example requests
Check the health of web01 and show the evidence source.Show the EC2 metrics for web01 over the last 60 minutes.Find recent errors for web01 during the last 15 minutes.Check the nginx service state on web01.Read the nginx journal for web01 over the last 30 minutes.Show recent AWS control-plane activity associated with web01 and identify
whether each event came from the administrator or MCP runtime role.A broader investigation could ask:
Investigate why nginx on web01 appears unavailable. Correlate EC2 health,
CloudWatch metrics, recent errors, nginx service state, the nginx journal, and
recent AWS control-plane activity. Separate confirmed evidence from inference,
state the limitations, and do not perform remediation.Troubleshooting
Terraform returns AccessDenied
Confirm Terraform is using the source or administrator profile:
export AWS_PROFILE=defaultThe MCP runtime role is intentionally unable to manage the Terraform infrastructure.
The MCP server rejects its AWS identity
Check:
AWS_PROFILEAWS account ID
Runtime role ARN
MCP_EXPECTED_AWS_ACCOUNT_IDMCP_EXPECTED_AWS_ROLE_NAMEThe source profile’s current authentication session
Confirm the runtime identity:
aws sts get-caller-identity --profile mcp-lab-runtimeThe ARN should include:
assumed-role/aws-infra-ops-mcp-lab-runtime/CloudWatch Logs returns AccessDenied
Confirm the current Terraform-managed runtime policy has been deployed.
The approved CloudWatch log-group resource ARNs must include the suffix required for querying their streams.
Service status or journal requests fail
Confirm:
web01is online in Systems ManagerSSM Agent is running
The custom SSM documents exist
The runtime policy references the approved documents and instance
The request uses
web01andnginx
Recent errors are empty
Confirm:
CloudWatch Agent is running
The approved log groups contain current streams
The requested time range covers the expected event
The event matches the server’s fixed error query
Recent CloudTrail changes are empty
CloudTrail Event History is eventually consistent. Wait several minutes and retry with an appropriate lookback.
An empty result does not prove that no activity occurred.
Codex does not show the tools
Confirm:
The MCP configuration uses absolute paths
The virtual environment contains the package
The server starts successfully
Codex was restarted after the configuration changed
Current limitations
Only
web01is supported.Only the
nginxservice is supported.Dynamic fleet discovery is not implemented.
There is no HTTP or end-to-end application reachability tool.
CloudWatch log groups are fixed to the lab instance.
The journal tool cannot inspect arbitrary services or files.
CloudTrail results cover a fixed event allowlist.
Terraform state is local.
The example lab uses a public subnet for outbound connectivity.
Diagnostics are read-only.
Recovery remains operator-controlled.
Teardown and cost control
Teardown is destructive.
Use the Terraform source or administrator profile—not the MCP runtime role:
export AWS_PROFILE=default
terraform -chdir=infrastructure plan -destroy -out=destroy.tfplanReview the saved plan carefully.
Apply only the reviewed destroy plan:
terraform -chdir=infrastructure apply destroy.tfplanVerify that Terraform no longer tracks any resources:
terraform -chdir=infrastructure state listDestroying the AWS resources stops their ongoing infrastructure costs. It does not remove the local source code, Git history, virtual environment, or Terraform files.
Future enhancements
Potential future improvements include:
Tag-based dynamic discovery of approved instances
Bounded fleet-health tools
Read-only HTTP or load-balancer health checks
Cross-account diagnostics using controlled role assumption
Remote MCP hosting
Multi-user authentication and authorization
Encrypted remote Terraform state with locking
Central application audit logging
Human-approved remediation workflows in a separately controlled service
Disclaimer
This project is a learning and demonstration environment. Review its IAM policies, networking, logging, data handling, and operational controls before adapting it for production use.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityCmaintenanceA read-only MCP server that lets an LLM inspect an AWS account — list EC2 instances, S3 buckets, IAM users, and cost — with a structural guarantee against any mutations.MIT

masaro-infra-mcpofficial
Flicense-qualityCmaintenanceA secure MCP server providing read-only tools to interact with Cloudflare, Coolify, and other infrastructure services, enabling AI clients to safely diagnose and validate environments.- Flicense-qualityBmaintenanceA read-only MCP server that gives Claude Code secure, non-invasive access to infrastructure logs, service status, metrics, Ansible facts, and Docker state via SSH, with a strict command allowlist and no write operations.
- AlicenseAqualityAmaintenanceA safe, structured MCP server that lets AI inspect and operate a VPS through typed, allowlisted tools for nginx, PM2, SSL, UFW, fail2ban, with read-only defaults and opt-in mutations.692MIT
Related MCP Connectors
Scans MCP servers for tool poisoning, prompt injection and supply chain risks.
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
Hosted Amazon Seller and Vendor MCP server for Claude, ChatGPT, Cursor, Codex, Gemini, Copilot.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/nhkm95/aws-infra-ops-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server