☁️ AWS MCP Server
Read-only Model Context Protocol server for AWS resources — multi-region, caching, audit, and AI-ready.
📋 Overview
This MCP server exposes 60+ read-only tools across AWS services: identity, EC2, S3, IAM, Cost Explorer, CloudWatch, GuardDuty, CloudTrail, ELB, WAF, Route53, ECS, EKS, RDS, Lambda, and more.
| Flow | Description |
|---|---|
| 🔌 | MCP client connects to this server |
| 🛠️ | Server invokes AWS APIs (read-only) |
| 📤 | Returns resources, metrics, cost data to the AI agent |
🛠️ Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| ☁️ MCP Server | TypeScript, AWS SDK v3 | Protocol handler, tool dispatch |
| 📦 Runtime | Node.js (v18+) | Execution |
| 🔐 Auth | AWS credentials (keys, profiles, SSO) | AWS API calls |
🗣️ Languages
| Language | Used In |
|---|---|
| TypeScript | MCP server, tools, CLI, libs |
| JSON | Config (mcp-config.json), MCP schema |
📁 Project Structure
├── src/
│ ├── index.ts # MCP server entry, tool dispatch, resources, prompts
│ ├── load-env.ts # Loads .env before other modules
│ ├── clients.ts # Shared AWS clients (one per service)
│ ├── cli.ts # Local CLI for testing tools
│ ├── integration.test.ts
│ └── lib/ # config, cache, retry, audit, rate-limit, webhook, etc.
├── docs/ # TOOLS.md, IAM_PERMISSIONS.md, CONFIG.md, TROUBLESHOOTING.md
├── mcp-config.json.example # Optional: webhook, rate limit, defaults (copy to mcp-config.json)
├── Dockerfile # Container image for running the server
└── .env # AWS credentials (copy from .env.example)
⚡ Capabilities
| Feature | Description |
|---|---|
| Multi-region | region parameter on EC2, VPCs, RDS, Lambda tools |
| Pagination | max_results on list_iam_users, list_s3_buckets, list_ecs_clusters, list_dynamodb_tables, list_cloudformation_stacks |
| MCP resources | Browse aws://region/service/id (identity, EC2, S3, cost, RDS, Lambda, GuardDuty) |
| MCP prompts | AI guidance for cost, security, and resource-list queries |
| Caching | Optional in-memory cache (TTL via MCP_AWS_CACHE_TTL) |
| Retry | Exponential backoff for throttled AWS calls |
| Audit log | Log tool invocations when MCP_AWS_AUDIT_LOG=true |
| Dry-run | Mock data when MCP_AWS_DRY_RUN=true (no AWS calls) |
| LocalStack | Set AWS_ENDPOINT_URL=http://localhost:4566 |
| Health check | aws_health_check tool to verify credentials |
| IAM policy | get_iam_policy_for_tools generates least-privilege policy |
| CLI | npm run cli -- get_aws_caller_identity for local testing |
| Config file | mcp-config.json for webhook, rate limit, defaults |
| estimate_cost | Rough cost estimate for EC2, Lambda, RDS, S3 |
| scan_secrets_risks | Find Secrets Manager secrets needing attention |
| Tag filter | tag_filter on list_ec2_instances, list_rds_instances |
| SSO / cross-account | See docs/SSO_AND_CROSS_ACCOUNT.md |
📖 Documentation: TOOLS.md · IAM_PERMISSIONS.md · CONFIG.md · TROUBLESHOOTING.md
🚀 Quick Start
# 1. Configure environment
cp .env.example .env # Add AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
# 2. Install and build
npm install
npm run build
# 3. Test locally (dry-run, no AWS calls)
MCP_AWS_DRY_RUN=true npm run cli -- get_aws_caller_identity
MCP Client Configuration
{
"mcpServers": {
"aws-mcp": {
"command": "node",
"args": ["/absolute/path/to/dist/index.js"],
"env": {
"AWS_ACCESS_KEY_ID": "YOUR_ACCESS_KEY",
"AWS_SECRET_ACCESS_KEY": "YOUR_SECRET_KEY",
"AWS_REGION": "us-east-1"
}
}
}
}
📦 Sharing with Your Team
Option A: Git
- Push to a private repo.
- Team clones, runs
npm install && npm run build. - Point MCP client at
dist/index.js(absolute path).
Option B: Package (.tgz)
npm pack # Creates mcp-server-aws-1.0.0.tgz
npm install -g mcp-server-aws-1.0.0.tgz
Then configure MCP client with "command": "mcp-server-aws".
Option C: Docker
docker build -t mcp-server-aws .
docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_REGION mcp-server-aws
🔧 Development
npm run dev # Watch mode
npm run typecheck # TypeScript check (no emit)
npm run cli -- <tool> [--arg key=value] # Test tools locally
npm run lint # ESLint
npm run format # Prettier
npm test # Unit + integration tests (28 tests)
Release: Push a tag (e.g. v1.0.1) to trigger a GitHub release with built artifacts.
👤 Author
Sergio Sediq
- 🔗 GitHub
- ✉️ sediqsergio@gmail.com