How I built CloudOps Assistant — a Slack bot that analyzes cloud infrastructure through conversation
I was tired of bouncing across 5–6 AWS consoles for routine ops on my own infra, so I tried wiring an AWS MCP server straight into a Slack bot. "Just an LLM with tools" — easy, right?
It broke in three ways that are probably pretty common once MCP leaves a single-developer setup.
Single-session design. The MCP server is built around one credential set per process. As soon as the bot needs to handle more than one identity — multiple users, or even one person juggling several AWS accounts and roles — you're either leaking permissions or serializing everything behind a single credential.
Slack's response window vs. real analysis time. Useful queries ("which ECS service drove the cost spike this week?") take 20–60s and multiple tool calls. Slack times out long before the LLM is done.
One-shot tool calls aren't enough. Almost every useful query was a chain: list resources → filter → fetch metrics → correlate. The model needs to loop until it decides it has the answer, not stop after the first tool returns.
So I rewired it.
- Per-identity MCP proxy. Each identity gets an isolated subprocess where its STS AssumeRole credentials are injected. Pooled, not one-per-request, so cold starts don't kill UX.
- SQS between Slack and the worker. Slack ack returns immediately; the worker processes async and posts back into the thread. Timeouts stop being a thing.
- Agent loop, not single tool call. The LLM keeps calling tools (Cost Explorer → CloudWatch → tag lookups → IAM) until it claims it's done. Bounded by max-iterations and a budget.
Cost spike investigations, "find anything publicly exposed", and "what caused yesterday's RDS CPU spike" are all answerable from Slack now, without opening a console.
Honestly the LLM was the easy part. The interesting work was the permission boundary and execution flow around it.
Curious how others have handled credential isolation when putting LLM agents in front of cloud infra — a proxy-per-identity feels heavy but I haven't found a cleaner pattern.