https://github.com/mrjhonyvidal/eks-ai-ops-toolkit
AI-powered Ops Toolkit for EKS featuring proactive incident resolution and an interactive Slack chatbot with MCP/Strands tool calling.
https://github.com/mrjhonyvidal/eks-ai-ops-toolkit
aws eks mcp strands-agents
Last synced: 17 days ago
JSON representation
AI-powered Ops Toolkit for EKS featuring proactive incident resolution and an interactive Slack chatbot with MCP/Strands tool calling.
- Host: GitHub
- URL: https://github.com/mrjhonyvidal/eks-ai-ops-toolkit
- Owner: mrjhonyvidal
- License: mit
- Created: 2026-05-10T00:40:43.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-10T16:07:28.000Z (about 2 months ago)
- Last Synced: 2026-05-10T16:34:29.240Z (about 2 months ago)
- Topics: aws, eks, mcp, strands-agents
- Language: Python
- Homepage:
- Size: 93.8 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# EKS AI Ops Toolkit
AI-powered Ops Toolkit for EKS featuring proactive incident resolution and an interactive Slack chatbot with MCP/Strands tool calling.

Serverless AI operations toolkit for EKS with two reusable capabilities in one repository:
1. **Proactive AI monitoring**: automatic EKS issue detection, analysis, Slack notification, optional GitHub auto-fix PR.
2. **Interactive Slack bot**: Slack Q&A for EKS troubleshooting using an orchestrator + specialist + MCP-backed tools.
## Architecture
### Proactive flow
```mermaid
graph LR
A[EventBridge / CloudWatch] --> B(Proactive Handler)
B --> C[EKS AI Toolkit]
C --> D[(DynamoDB Record)]
C --> E[Slack Update]
C --> F[GitHub PR Auto-fix]
```
### Interactive flow (re:Invent-style semantics)
```mermaid
graph LR
A[Slack Interface] --> B(K8S Orchestrator Agent)
B --> C{Intent?}
C -->|Non-K8s| D[Early Exit]
C -->|K8s Troubleshooting| E[K8S Specialist Agent]
E <--> F[Amazon EKS Hosted MCP Tools]
```
### Concrete code mapping
- Proactive Lambda entrypoint: `eks_ai_ops.proactive.handler.handler`
- Proactive orchestration: `eks_ai_ops.proactive.flow.ProactiveIncidentFlow`
- Interactive Lambda entrypoint: `eks_ai_ops.interactive.handler.handler`
- **K8S Orchestrator Agent**: `eks_ai_ops.interactive.orchestrator.K8sOrchestratorAgent`
- Intent classifier: `eks_ai_ops.interactive.orchestrator.K8sIntentClassifier`
- **K8S Specialist Agent**: `eks_ai_ops.interactive.strands_agent.InteractiveEKSAgent`
- MCP adapter: `eks_ai_ops.interactive.mcp_tools`
- Backward-compatible wrappers: `eks_ai_ops.handler`, `eks_ai_ops.bot_handler`
## Repository structure
```text
src/eks_ai_ops/
proactive/
handler.py
flow.py
interactive/
handler.py
orchestrator.py
strands_agent.py
mcp_tools.py
shared/
config.py
prompts.py
```
## Prerequisites
- Python 3.11+
- AWS account with permissions for Lambda, EventBridge, CloudWatch, DynamoDB, IAM, API Gateway
- Slack workspace where you can create/install apps
- Optional:
- Bedrock access for Nova/Claude models
- Strands SDK (`pip install -e ".[strands]"`)
- MCP gateway that exposes EKS tools
## Installation
```bash
cp .env.template .env
pip install -e ".[dev]"
```
Optional specialist backend extras:
```bash
pip install -e ".[strands]"
```
## Environment variables
Use `.env.template`.
### Shared
- `AWS_REGION` (default: `us-east-1`)
- `LLM_PROVIDER` (`bedrock` or `anthropic`)
- `BEDROCK_MODEL_ID`
- `CLUSTER_NAME`
- `INCIDENT_TABLE`
- `DEPLOY_TABLE`
### Slack
- `SLACK_BOT_TOKEN`
- `SLACK_CHANNEL`
- `SLACK_SIGNING_SECRET`
### Proactive flow
- `GITHUB_TOKEN`
- `GITHUB_REPO`
- `GITHUB_BASE_BRANCH`
- `KUBECTL_LAMBDA`
### Interactive flow
- `INTERACTIVE_AGENT_BACKEND` (default `strands`)
- `EKS_MCP_SERVER` (default `eks`)
- `MCP_GATEWAY_URL`
- `MCP_GATEWAY_API_KEY` (optional)
- `INTENT_USE_LLM` (`false` by default)
- `INTENT_MODEL_ID` (default: `us.amazon.nova-micro-v1:0`)
## MCP gateway (interactive bot)
The interactive specialist calls Kubernetes tools through an HTTP MCP gateway.
Set `MCP_GATEWAY_URL` to a service that accepts:
```text
POST {MCP_GATEWAY_URL}/tools/call
{ "server": "eks", "tool": "list_pods", "arguments": { "namespace": "api" } }
```
Tools dispatched today: `list_pods`, `describe_resource`, `get_pod_logs`
(see `src/eks_ai_ops/interactive/mcp_tools.py`).
If `MCP_GATEWAY_URL` is empty, the bot still answers via the LLM-only fallback —
useful for a first run without standing up a gateway. Add an API key with
`MCP_GATEWAY_API_KEY` if your gateway requires bearer auth.
### Picking a gateway
`MCP_GATEWAY_URL` is **not** an AWS-managed endpoint — it's whatever HTTP
service speaks the contract above. Options, easiest first:
1. **AWS Labs `eks-mcp-server`** (recommended) — official open-source MCP
server with EKS-aware tools. It speaks MCP-over-stdio out of the box, so
you wrap it behind a thin HTTP shim that translates `POST /tools/call` →
MCP `tools/call`. Repo: (see
`src/eks-mcp-server/`).
2. **Self-host the shim on AWS:**
- **App Runner** — simplest. Push a container, get an HTTPS URL, point
`MCP_GATEWAY_URL` at it.
- **ECS Fargate behind ALB** — if you need VPC peering with EKS.
- **Lambda + Function URL** — fine for low traffic; cold starts add latency.
3. **kubectl in-VPC** — `KubectlHelperFunction` already runs inside the EKS
VPC and can reach the cluster API. The MCP gateway can delegate to it for
real `kubectl` calls (this is how the AWS Labs server talks to the cluster
too).
Auth: store any API key in SSM as `/eks-ai-ops-toolkit/mcp-gateway-api-key`
(SecureString) and add a corresponding parameter mapping to
`infrastructure/template.yaml` if you want it injected automatically. Until
then `MCP_GATEWAY_API_KEY` is read from the Lambda environment.
> **Quickest path:** skip the gateway. The Slack bot will answer Kubernetes
> questions from Bedrock alone. Add the gateway later when you want the bot
> to actually run `kubectl` against a cluster.
## Kubectl helper VPC (SSM parameters)
The `KubectlHelperFunction` Lambda runs inside the EKS VPC so it can reach the
cluster API. Before `make deploy` you must publish three SSM parameters:
```bash
aws ssm put-parameter --name /eks-ai-ops-toolkit/eks-vpc-id \
--value vpc-xxxxxxxx --type String --overwrite
aws ssm put-parameter --name /eks-ai-ops-toolkit/eks-private-subnet-1 \
--value subnet-aaaaaaaa --type String --overwrite
aws ssm put-parameter --name /eks-ai-ops-toolkit/eks-private-subnet-2 \
--value subnet-bbbbbbbb --type String --overwrite
```
Use private subnets that have a route to the EKS control plane and to NAT for
pulling Bedrock/STS endpoints.
## Engineer journey 1: Greenfield (AWS + Slack only)
### Step 1: Create/configure Slack app
1. Create app in Slack API console.
2. Add bot scopes:
- `chat:write`
- `app_mentions:read`
- `channels:history`
3. Enable Event Subscriptions.
4. Subscribe to `app_mention`.
5. Enable Interactivity.
6. Install app into workspace and invite bot to your target channel.
### Step 2: Configure AWS secrets (SSM)
Use helper target:
```bash
make setup-ssm
```
### Step 3: Build and deploy with SAM
```bash
make build
make deploy
```
After deploy, capture `SlackBotEndpoint` from stack outputs and set it in:
- Slack Event Subscriptions Request URL
- Slack Interactivity Request URL
### Step 4: Verify end-to-end
- Trigger/emit an alarm event and confirm proactive Slack alert appears.
- Mention bot in thread with EKS question and verify orchestrator route behavior.
## Engineer journey 2: Existing EKS project wants SlackBot + AI monitoring
### Step 1: Keep current EKS; integrate this stack
- Reuse existing cluster name by passing `ClusterName` parameter on deploy.
- Reuse existing alarm conventions or route your existing events into EventBridge patterns expected by template.
### Step 2: Connect to existing ops repositories
- Set `GITHUB_REPO` to infra repo where you want auto-fix PRs.
- Keep PR auto-merge disabled; human review remains required.
### Step 3: Integrate MCP gateway for interactive troubleshooting
- Point `MCP_GATEWAY_URL` to your existing EKS MCP service.
- Set `EKS_MCP_SERVER` if your MCP server identifier differs from default.
### Step 4: Roll out safely
- Deploy to a non-prod Slack channel first.
- Validate non-K8s questions are exited by orchestrator.
- Validate K8s troubleshooting questions route to specialist and use MCP tools.
## GitHub Actions (CI/CD)
The repository includes GitHub Actions workflows for continuous integration (`ci.yml`) and automated deployment (`deploy.yml`).
- **Continuous Integration (`ci.yml`):** Runs automatically on every push and pull request to `main` to run linting and tests.
- **Automated Deployment (`deploy.yml`):** By default, this workflow is set to `workflow_dispatch` (disabled from running automatically) to prevent unexpected AWS deployments if you are just evaluating the toolkit locally.
### How to Enable Automated Deployments
If you want the pipeline to automatically deploy your infrastructure on merge:
1. **Enable Triggers:** Edit `.github/workflows/deploy.yml`. Change `on: workflow_dispatch:` to:
```yaml
on:
push:
branches: [ main ]
```
2. **Set Secrets in GitHub:** Go to your repository **Settings > Secrets and variables > Actions**.
- Add a repository variable `AWS_REGION` (e.g., `us-east-1`).
- Add a repository variable `EKS_CLUSTER_NAME`.
- Add a repository variable `SLACK_CHANNEL`.
- Add a repository variable `GITHUB_REPO`.
- Add a repository secret `AWS_DEPLOY_ROLE_ARN` (An IAM Role ARN configured for GitHub OIDC to deploy the SAM stack).
Once configured, the CI pipeline will run Ruff/Pytest on every PR, and the Deploy pipeline will build and update your AWS SAM stack whenever code is merged to `main`.
## Local run and testing
### Run checks
```bash
ruff check src tests
python -m compileall src tests
pytest --no-cov
```
### Run focused architecture tests
```bash
pytest --no-cov tests/test_orchestrator.py tests/test_bot_handler.py
```
### Local proactive invoke example
```bash
python -c "
from eks_ai_ops.proactive.handler import handler
event = {
'source': 'aws.cloudwatch',
'detail': {
'alarmName': 'sre-prod-api-checkout-error-rate-high',
'state': {'value': 'ALARM', 'reason': 'Threshold crossed'},
'previousState': {'value': 'OK'},
'configuration': {}
}
}
print(handler(event, None))
"
```
### Local observation tip (k9s)
While testing in a real cluster, use `k9s` to watch pod logs and events in parallel with Slack interactions.
This makes it easier to verify whether orchestrator routing and specialist troubleshooting outputs match live cluster state.
## Deploy commands summary
```bash
make install
make test-fast
make build
make deploy
```
If already configured and iterating:
```bash
make deploy-fast
```
## Cleanup and Teardown
When you're done using the toolkit, remove all AWS resources to avoid unnecessary charges:
### Basic Cleanup
Delete the main CloudFormation stack and associated resources:
```bash
make destroy-confirm
```
This removes:
- Lambda functions
- DynamoDB tables (marked for retention)
- CloudWatch log groups
- SSM parameters
- CloudWatch alarms
### Complete Cleanup
To also delete EKS cluster and all EC2 instances (if deployed with eksctl):
```bash
make destroy-all
```
### Verify Cleanup
Check that all resources have been deleted:
```bash
make verify-cleanup
```
### Detailed Cleanup Guide
For comprehensive instructions, troubleshooting, and step-by-step cleanup of individual resources, see [CLEANUP.md](./CLEANUP.md).
### Cost Considerations
- EKS clusters charge hourly (plus data transfer costs)
- EC2 instances charge by the second
- NAT gateways charge hourly
- Data transfer across AZs incurs charges
**Recommendation**: Run `make destroy-confirm` or `make destroy-all` when not actively developing to avoid unexpected AWS bills.