DEV Community

Lovee Jain for AWS Community Builders

Posted on • Originally published at Medium

Extending MCP Agents with the AWS MCP Server: Why Python ADK Shines?!

Image generated with Chat-GPT showing power of MCP servers with ADKSo if you have read Part 1: Chaining MCP Servers with Gemini ADK — The TypeScript Story!, you already know the pain I had when trying to use AWS MCP Server with ADK in Typescript — the type conversions that ADK does when listing the tools from AWS MCP server have type mismatches, due to which it is unable to register the tool we need for our next step.

But fear not, I have submitted a PR for the fix and until is approved and merged🤞🏻, let’s continue with the Python version.

For those who missed the context, here’s a TLDR;

  1. We are creating the standard local MCP server that gives us weather of any US location.
  2. However, for this work it really needs the latitude/longitude of the place, which we will get from Google Maps MCP Server.
  3. Finally for this part, we will publish the weather update to an AWS SNS Topic which is subscribed by our email — so we get the direct weather update!

And we call all these MCP servers from Google’s Agent Development Kit (ADK).

Are you ready?

Prerequisites:

  1. We are using the same weather MCP server that we created in Part 1: Chaining MCP Servers with Gemini ADK — The TypeScript Story! Find highlighted Create the weather MCP server in the post for instructions.
  2. MCP Inspector — for checking out tools offered by different MCP servers.
  3. Finally ADK — this time with Python, so you need to have Python 3.10 or later and pip for installing packages. Just install ADK by running the following command:
pip install google-adk
Enter fullscreen mode Exit fullscreen mode

Create ADK Project and use it as an MCP Client:

It is super easy to get started with ADK when you are using Python. You can find the documentation here or follow the steps below:

  • Let’s create the a ADK project:
adk create weather_adk_python
Enter fullscreen mode Exit fullscreen mode

This will create a basic agent that you can chat with. Feel free to test and play.

But for now we will move on and start creating MCP toolsets so that we can use our local weather MCP server and remote Google Maps MCP server! You can replace all the code with the following sections.

  • First, let’s add some imports:
import os
from google.adk.agents.llm_agent import LlmAgent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from mcp import StdioServerParameters
Enter fullscreen mode Exit fullscreen mode
  • Next, let’s define the weather MCP toolset:
get_weather = McpToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command="node",
            args=["local/path/to/weather_mcp_adk_python/weather_mcp_server/build/index.js"], # Add the correct local path to your MCP server build
        ),
    )
)
Enter fullscreen mode Exit fullscreen mode
  • Next, let’s define Google Maps MCP toolset. Please note: You can find the instructions to get the Google Maps API Key from Part 1.
google_maps_api_key = os.environ.get("GOOGLE_MAPS_API_KEY")
if not google_maps_api_key:
    raise ValueError("GOOGLE_MAPS_API_KEY environment variable is not set")

get_coordinates = McpToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command='npx',
            args=[
                "-y",
                "@modelcontextprotocol/server-google-maps",
            ],
            env={
                "GOOGLE_MAPS_API_KEY": google_maps_api_key
            },
        ),
    ), tool_filter=["maps_geocode"]
)
Enter fullscreen mode Exit fullscreen mode
  • Finally, define the root_agent:
root_agent = LlmAgent(
    model='gemini-2.5-flash',
    name='root_agent',
    description='A helpful assistant for finding the coordinates and telling weather in a US city/place.' ,
    instruction=(
        "You can use 'get_coordinates' tool to get the coordinates of a US location. " 
        "Once you have the coordinates, you can pass it to 'get_weather' tool to get the weather of that US location."
    ),
    tools=[get_weather, get_coordinates]
)
Enter fullscreen mode Exit fullscreen mode

Now, this brings you to parity with the TS version we created in Part 1. That means it will chain your MCP calls and give you the weather update for any US location without you having to look for lat/long of that place. Let’s try it — with UI:

adk web
Enter fullscreen mode Exit fullscreen mode

Chaining MCP servers in ADK

It works like cake! Let’s add some icing to it — let’s send this weather update to your email! How do we do that? Well, first we create an AWS SNS Topic and subscribe to it. And then use the AWS MCP server to publish the weather updates to the topic.

Create AWS Topic and Subscription:

I want to mention something important before we go ahead into some clickops. Here’s the documentation on AWS MCP servers and I highly recommend inspecting the AWS SNS-SQS MCP Server first so that we know the capabilities. You can do so by running:

npx @modelcontextprotocol/inspector
Enter fullscreen mode Exit fullscreen mode

Please Note: The authorization between the MCP server and your AWS accounts are performed with AWS profile you setup on the host. If you have multiple AWS profiles in your system and you would like to use a different profile than the default one, you will need to set AWS_PROFILE in the Environment Variables before connecting to the server or you can run the inspector with the profile set:

AWS_PROFILE=myprofile npx @modelcontextprotocol/inspector
Enter fullscreen mode Exit fullscreen mode

This will open the inspector where you can then list tools and explore more:

Inspecting tools in AWS SNS-SQS MCP server with MCP inspector<br>

You’d find it interesting that the AWS SNS-SQS MCP Server offers tools to create SNS Topics, subscriptions and even confirm the subscription via MCP too! However, for our example we will do these steps manually and regardless, you cannot confirm the email subscription directly using the tool because it requires a token that is only available to the user.

But, we will use the publish tool within ADK to publish the weather updates to the topic that we have subscribed.

So let’s create the topic and subscribe using clickops.

  • Once you have logged in, navigate to SNS and create a new standard topic: weather.

Creating a new Topic<br>

Please Note: You need to tag this topic with mcp_server_version because only mcp_server_version tagged resources can be accessed by the MCP Server as a security measure. FYI, it’s value is not validated, it works as long as the tag is set to some value.

  • Create a new Subscription: Select the right topic, type as Email and put down your email in the enpoint.

  • Soon, you will get an email to confirm the subscription, confirm it.

And done ✅. Copy the Topic ARN as you will need it in the next steps.

Use AWS MCP Server in ADK:

Let’s get back to our ADK and modify it. First, we will define some variables:

TOPIC_ARN = "arn:aws:sns:ap-southeast-2:123456789:weather"
AWS_REGION = "ap-southeast-2"
AWS_PROFILE = "myprofile"
Enter fullscreen mode Exit fullscreen mode

Next, we create an MCP toolset for AWS SNS and just expose the publish tool:

publish_sns = McpToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command="uvx",
            args=["awslabs.amazon-sns-sqs-mcp-server@latest"],
            env={
                "AWS_PROFILE": AWS_PROFILE
            }
        ),
    ),
    tool_filter=["publish"],
)
Enter fullscreen mode Exit fullscreen mode

Now, if you inspected this tool earlier, you will find that you need to pass in the Topic ARN and the AWS Region as arguments, it cannot pick them up from the environment variables. And hence we will use the power of instructions and description in our root agent so that it picks up the right ARN and region without asking user to put those in.

Replace the root_agent part with the following:

root_agent = LlmAgent(
    model='gemini-2.5-flash',
    name='root_agent',
    description='A helpful assistant for finding the coordinates, telling weather in a US city/place and publishing the weather summary to SNS topic.',
    instruction=(
        "You can use 'get_coordinates' tool to get the coordinates of a US location. " 
        "Once you have the coordinates, you can pass it to 'get_weather' tool to get the weather of that US location. " 
        "Once prompted, you can use 'publish_sns' tool to send the weather summary as message or if the user can do any outdoor activities based on the weather to SNS topic. "
        f"Use {TOPIC_ARN} as topic ARN and {AWS_REGION} as region. Do not ask the user for it." 
    ),
    tools=[get_weather, get_coordinates, publish_sns],
)
Enter fullscreen mode Exit fullscreen mode

And that’s it — let’s give it a go!

adk web
Enter fullscreen mode Exit fullscreen mode

ADK with 3 different MCP tools

Weather update from AWS SNS Topic on Email

Hoorayyy!!! It works! We can now get some weather summaries and whether we can do some outdoor activities as per the weather in a particular US city — right into our inbox!

Save Yourself the Headache:

While implementing this was so much fun, it did come with a bit of a headache. So let me help you save it!

  • Do not forget to use the right Topic ARN and AWS Region — they are key or else you will get stuck in this infinite loop of not being able to publish to your Topic without a proper error message.
  • It is also the power of writing good instructions and descriptions of your agent that can yield different results, after all, it is an LLM and it is non-deterministic and can never give you the same response.
  • Do not forget to tag your AWS Topic — else you cannot publish!
  • If you have multiple AWS Profiles, I have found it really hard to get consistent results — sometimes it somehow picks the wrong or the default profile even after we are setting the right one in the environment variables. So I actually have also tried setting it up before calling adk web like this: export AWS_PROFILE=<profile_name>. It is also recommended in the ADK docs to set environment variables before running adk web.
  • Last, but not the least, if your toolsets also timeout when initialising, you can optionally set a higher timeout in your connection_params to prevent it.

Here’s the Github repo with all the code you need!

And if you are thinking what I am thinking, yes I potentially want to deploy all this and create something production-ready! So there’s a chance of next part to this series.

Meanwhile happy experimenting!! 🔍

Top comments (0)