Skip to main content

Command Palette

Search for a command to run...

I've tried the AWS MCP Server

A journey through the evolution of AI-Infrastructure integration

Updated
5 min read
P

👋 Hi, I’m @hpfpv ☁️ I’m a Cloud Infrastructure Architect | 8x AWS Certified 🚀 I build secure, scalable, and automated solutions on AWS using Terraform, CloudFormation, and CI/CD 📚 Always exploring hybrid cloud, serverless, and AI-driven architectures

Hi guys!

So years ago, GenAI was emerging and I gave a presentation about how to apply Generative AI to everyday business processes. The goal was simple: showcase what was possible with services like Amazon Bedrock and demonstrate how AI could transform how we work.

One scenario stuck with people:

Mr. Nobody wants to talk to his AWS resources.
He speaks; a bot listens; it pulls context from the environment and, when asked, takes action.

Back then, that was more vision than product. Amazon Q was still young and couldn’t reach into the console the way we wanted. If you needed an assistant for AWS infrastructure, you had to build your own.

Fast-forward to today: Amazon Q can now provide details about your resources right inside the console. The thing that felt “impossible” turned into a menu option. So why bother building your own at all?

Because the path from proof-of-concept to production reality teaches you when to build, when to buy, and how the underlying architecture is changing.

Goals & Constraints

For this scenario, my goals were simple:

  • Make an application that will work simpler with AI

  • Boost day-to-day productivity

  • Plug in enterprise context (AWS resources across multiple accounts)

  • Keep the overall infrastructure fast and cheap enough to matter

At that time, building a custom solution was the only way to explore this possibility. I knew I needed:

  • An LLM to understand natural language requests (Claude with Amazon Bedrock)

  • Custom tools to interact with AWS services/resources

  • An agent to orchestrate everything together

The plan on paper looked clean:

User → Agent → Custom Tools → AWS APIs → Answer/Action

I followed the standard pattern for AI agents at the time (at least to my knowledge then). I built custom Python functions to serve as tools for the agent:

def search_ec2_instances_by_tag(tag_key):
    """Custom tool to search EC2 instances by tag"""
    ec2 = boto3.client('ec2')
    response = ec2.describe_instances(
        Filters=[{'Name': f'tag:{tag_key}', 'Values': ['*']}]
    )
    # Process and return results...

def start_ec2_instance(instance_id):
    """Custom tool to start an EC2 instance"""
    ec2 = boto3.client('ec2')
    response = ec2.start_instances(InstanceIds=[instance_id])
    # Handle response...

Each tool required careful implementation, error handling, and testing. The LangChain integration looked like this:

tools = [
    Tool(
        name="search_ec2_instances_by_tag",
        func=search_ec2_instances_by_tag,
        description="Lists EC2 instances by tag key"
    ),
    Tool(
        name="start_ec2_instance", 
        func=start_ec2_instance,
        description="Starts an EC2 instance"
    )
    # ... more custom tools
]

agent = initialize_agent(
    tools, 
    llm, 
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    memory=memory,
    verbose=True
)

The tradeoffs

This approach worked but it came with significant challenges:

  • Every new AWS action was another tool to build, test, and document.

  • The wrappers had to keep up with AWS API changes.

  • Capability matched my free time, not business demand.

  • I was basically shipping a tiny, bespoke AWS CLI.

Great for a talk and demos. Less great for production and scale.

From Custom Tools to MCP

While Q matured inside the console, the Model Context Protocol (MCP) landed with a different promise: standardize how AI apps talk to tools and data. No more bespoke plumbing for every integration. Just a protocol and servers that expose capabilities in a consistent way.

AWS Labs shipped two official MCP servers I cared about:

  • aws-api: access to AWS operations

  • aws-docs: fast, contextual access to AWS documentation

The architecture simplified overnight:

My code shrank while the surface area grew.

class SimpleAgent:
    """Simplified agent that directly uses Bedrock and MCP servers."""

    def __init__(self, app_config, mcp_client, aws_session=None):
        self.app_config = app_config
        self.mcp_client = mcp_client
        self.aws_session = aws_session or boto3.Session()
        self.bedrock_client = None
        self.conversation_history = []
        self._initialized = False
        self._last_tool_calls = []

    async def _analyze_intent(self, user_message: str) -> Dict[str, Any]:
        """Analyze user intent and determine what tools to use."""
        ...
        # Get available tools
        available_tools = self.mcp_client.get_available_tools()
        tools_description = self._format_tools_for_prompt(available_tools)

        # Create intent analysis prompt with improved context awareness
        ...

What changed for me

  • Fewer moving parts. I dropped a lot of LangChain-specific orchestration and custom wrappers.

  • First-class AWS. Instead of my custom EC2 functions, I now have access to the full AWS CLI through the aws-api server

  • Built-in documentation. The aws-docs server provides something I never implemented in my custom solution: intelligent documentation access.

When Custom Still Wins

Q is excellent when you live inside the console. But custom assistants still win when you need:

  • Cross-tool workflows. AWS + Jira + GitHub + PagerDuty in one thread.

  • Multi-cloud or on-prem bridges. Q won’t run your GCP/Azure/VMware playbooks.

  • Custom guardrails. Your change windows, naming rules, org policy, and hand-offs.

  • Deep domain context. Proprietary docs, acronyms, runbooks, and tribal knowledge.

In other words: when your workflow isn’t just “ask AWS something,” custom still pays off.

Key Takeaways

Building this custom AWS assistant taught me several lessons that I think will remain relevant for a long time (I know, AI is moving fast…):

  1. Standards > Snowflakes. MCP changed the shape of the problem. I write less glue and deliver more capability.

  2. Build → Buy → Blend. Building teaches you enough to know what to buy later and eventually what to keep custom.

  3. Reduce learning debt. The value of the proof-of-concept wasn’t the code; it was the intuition about where agents help and where they get in the way.

Conclusion

More than the result, the lesson was understanding how the GenAI technology stack keeps evolving. Whether you're using Amazon Q (or similar), building custom solutions, or exploring MCP servers, understanding these architectural patterns helps you make better decisions about when to build, when to buy, and when to migrate.

The Model Context Protocol represents the current state of this evolution: standardized ways to integrate AI with external systems that remain valuable even as managed services continue expanding their capabilities.


The complete implementation, including both the custom tool approach and the MCP-based solution, is available in my GitHub repository.

A

So basically… we went from 'DIY AWS assistant' to 'AWS assistant with factory parts' 😄. MCP feels like the future for these integrations.