mcp-production-aws
README.md
# Production MCP on AWS (Bedrock + EKS/GitOps)
A production-oriented Model Context Protocol (MCP) platform: an MCP server
exposing tools, resources, and prompts over Streamable HTTP, secured with JWT
authentication and per-tool RBAC, consumed by an Amazon Bedrock (Claude) client,
and packaged for delivery on Amazon EKS via Helm, ArgoCD (GitOps), and GitLab CI/CD.
## Architecture
```
Developer push -> GitLab CI/CD (test -> build image -> push to ECR -> bump tag in Git)
|
v
ArgoCD (GitOps: watches Git, syncs to EKS)
|
v
Bedrock Claude client --(JWT over HTTPS)--> ALB Ingress -> Service -> MCP server pods (HPA)
| IRSA
v
AWS Secrets Manager (JWT key) + Bedrock
```
- **Authentication**: JWT (signing key from AWS Secrets Manager), verified in middleware.
- **Authorization**: per-tool RBAC (admin/user/guest), deny-by-default.
- **Transport**: Streamable HTTP (remote MCP).
- **Scaling**: multiple stateless pods behind a Service/ALB, autoscaled by HPA.
- **Security**: no static keys — IRSA for pods, Secrets Manager for the signing key.
## Repository layout
```
server/ MCP server + auth (JWT + RBAC)
client/ Bedrock Claude MCP client
scaling/ Round-robin load balancer (demonstrates LB internals)
deploy/Dockerfile Container image
deploy/helm/ Helm chart (Deployment, Service, Ingress/ALB, HPA, IRSA SA)
deploy/argocd/ ArgoCD Application (GitOps)
.gitlab-ci.yml CI/CD pipeline
```
## Status: implemented vs design
**Implemented and run locally**
- MCP server with tools, resources, and prompts (`server/mcp_server.py`)
- JWT auth + per-tool RBAC with 401/403 handling (`server/auth.py`)
- JWT signing key sourced from AWS Secrets Manager
- Bedrock Claude client with tool discovery + tool-use execution (`client/bedrock_client.py`)
- Round-robin load balancer with health checks (`scaling/load_balancer.py`)
- Container image (`deploy/Dockerfile`) built and run locally
**Delivered as config-as-code (validated with `helm lint` / YAML checks; deploy on a real EKS cluster)**
- Helm chart: Deployment, Service, ALB Ingress, HPA, IRSA ServiceAccount
- ArgoCD Application (automated sync, prune, self-heal)
- GitLab CI/CD (test -> build/push to ECR -> update image tag in Git)
## Prerequisites
- Python 3.12, an MCP-compatible environment (`pip install -r requirements.txt`)
- AWS account with Bedrock (Claude) access
- A secret in AWS Secrets Manager named `mcp/jwt-signing-key`
- For deployment: an EKS cluster, ECR repo, AWS Load Balancer Controller, ArgoCD
## Run locally
Create the JWT signing secret (one time):
```
aws secretsmanager create-secret \
--name "mcp/jwt-signing-key" \
--secret-string "$(python3 -c 'import secrets; print(secrets.token_urlsafe(48))')" \
--region us-east-1
```
Start the server:
```
cd server
uvicorn mcp_server:app --host 0.0.0.0 --port 8000
```
Run the Bedrock client (role is optional: user | admin | guest):
```
cd client
python bedrock_client.py "What is 5 plus 59?" user
python bedrock_client.py "reset the counter" admin
```
`/health` is public (for probes); all MCP requests require a valid JWT, and
tool calls are authorized per role.
## Notes
- Model ID and region are read from env (`BEDROCK_MODEL_ID`, `BEDROCK_REGION`)
to avoid hardcoding a model that may be retired.
- Secrets are never committed or baked into the image; they are fetched at
runtime (Secrets Manager) and, in EKS, accessed via IRSA.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues