May 12, 2026 10 min read
MCP for AWS: connecting S3, EC2, and Cost Explorer to Claude with zero infrastructure
AWS has no native MCP endpoint, so we built one. Cloud Horizon's AWS MCP server lets Claude ask about EC2 inventory, S3 buckets, CloudWatch logs, and Cost Explorer data in plain English. No agents, no Terraform, no VPC access. Here is how it works and what we learned.
AWS does not ship a Model Context Protocol (MCP) server for any of its services. There is no native way for Claude or Cursor to read your EC2 inventory, your S3 buckets, or your Cost Explorer data. Every team that wants this today either runs a local script or gives up.
Cloud Horizon built one. It is a Cloudflare Pages Function that exposes 7 AWS services as MCP tools. Each tool calls the AWS SDK with read-only credentials and returns structured data. No agents. No Terraform. No access to your VPC.
Why AWS is the hardest cloud to MCP
AWS APIs are fragmented across 300+ services. Each service has its own endpoint pattern, authentication model, and rate limits. IAM alone has over 10,000 actions. Building a single MCP server that covers the services most teams care about means making opinionated choices about scope.
We started with the six services that appear on every cloud bill: EC2, RDS, S3, Lambda, CloudWatch, and CloudFront. Then we added Cost Explorer because the question everyone actually wants to ask is "Why did my bill go up?"
Architecture: read-only by design
The AWS MCP server is stateless. Each tool invocation creates a
new AWS SDK client, signs the request with temporary credentials
(access key + secret key), makes the API call, and returns the
filtered result. The credentials are stored in Cloudflare Secrets
as AWS_ACCESS_KEY_ID and
AWS_SECRET_ACCESS_KEY.
We recommend an IAM user or role with exactly these permissions:
ec2:DescribeInstances,ec2:DescribeVolumes,ec2:DescribeSnapshotsrds:DescribeDBInstances,rds:DescribeDBClusterss3:ListAllMyBuckets,s3:GetBucketLocation,s3:GetBucketVersioninglambda:ListFunctions,lambda:GetFunctioncloudwatch:DescribeAlarms,cloudwatch:GetMetricDatace:GetCostAndUsage,ce:GetCostForecastcloudfront:ListDistributions,cloudfront:GetDistribution
No write actions. No Create, Delete, or
Modify. The worst-case leak is an attacker reads your
instance list and your S3 bucket names.
The tool surface
| Tool | What it returns |
|---|---|
aws_ec2_list_instances | Instances, types, states, AZs, tags, launch times |
aws_ec2_get_metrics | CPU, network, disk for a specific instance over 24h |
aws_rds_list_instances | DBs, engines, versions, storage, Multi-AZ status |
aws_s3_list_buckets | Buckets, regions, versioning, encryption, size estimates |
aws_lambda_list_functions | Functions, runtimes, memory, timeout, last modified |
aws_cloudwatch_list_alarms | Alarm names, states, metrics, thresholds |
aws_cost_get_summary | MTD spend, service breakdown, daily trend, forecast |
aws_cloudfront_list_distributions | Distributions, origins, cache behaviors, statuses |
Demo mode: explore before you connect
Every tool has a demo path. If no AWS credentials are configured, the server returns realistic mock data: 12 EC2 instances, 4 RDS databases, 8 S3 buckets, 6 Lambda functions, 3 CloudWatch alarms, and a Cost Explorer summary. The structure matches the real AWS SDK responses exactly. When you add credentials, the same queries return live data.
Asking questions in plain English
Here is what Claude can do with the AWS MCP server connected:
- "List my EC2 instances in us-east-1 that are not tagged Owner"
- "What is the CPU utilization trend for i-0a1b2c3d over the last week?"
- "Which S3 buckets do not have versioning enabled?"
- "Show me Lambda functions with memory above 1GB and timeout above 60s"
- "Break down my AWS bill by service for this month"
- "Which CloudFront distributions have 0 requests in the last 7 days?"
The AI translates each question into tool calls, runs them in parallel where possible, and synthesizes the results into a readable answer. No SQL. No CLI. No dashboard hunting.
What we learned building this
AWS rate limits are the biggest practical constraint. The Cost Explorer API allows 10 requests per second per account. CloudWatch GetMetricData allows 50 transactions per second. The MCP server batches requests aggressively and caches results for 60 seconds to stay under limits.
Pagination is the second. Every AWS list call returns up to 1,000
items with a NextToken. The MCP server follows
pagination automatically and returns the complete dataset in a
single response. The client never sees tokens.
The third lesson: regional endpoints matter. The EC2 tool defaults to the region configured in the credentials. For multi-region accounts, the tool iterates over all enabled regions in parallel.
What is next
VPC flow logs analysis. ECS cluster inventory. Route 53 health check audit. EBS snapshot cost attribution. SNS topic inventory. Every AWS service that exposes a read API belongs in the MCP server eventually.
The server is open source at cloudevolvers/cloudsight. The MCP config lives at /.well-known/mcp.json.