
Model Context Protocol (MCP) and Amazon Bedrock
Getting started with Anthropic's LLM protocol on AWS
MCP is an open protocol released by Anthropic that standardizes how applications provide context to LLMs. Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools.
- Stdio transport
- Uses standard input/output for communication
- Ideal for local processes
- HTTP with SSE transport
- Uses Server-Sent Events for server-to-client messages
- HTTP POST for client-to-server messages
We'll follow the journey of the simple prompt
get me a summary of the blog post at this $URL
depicted in the two pictures below step by step, so it's easy to follow along.
- For a human the task of reading a web page and provide its summary is trivial, but LLMs are not normally able to visit web pages and fetch context outside of their parametric memory. This is why we need a tool.
- We provide the user prompt and a list of available tools brokered by our MCP server to Amazon Bedrock via Converse API. In this case, Amazon Bedrock is acting as our unified interface to many models.
- Based on the user prompt and the tool inventory the chosen model plans a proper response.
- In this case the model correctly plans to use the
visit_webpage
tool to download the content at the URL provided. Bedrock returns atoolUse
message to the client, including thename
of the selected tool, theinput
for the tool request, and a uniquetoolUseId
which can be used in subsequent messages. Read these docs for more information about the syntax and usage oftoolUse
in Bedrock Converse API. - The client is programmed to forward any
toolUse
message to the MCP server.
In our implementation, communication happens viaJSON-RPC
overstdio
on the same machine - The MCP server dispatches the
toolUse
request to the appropriate tool visit_webpage
tool is invoked and an HTTP request is made to the provided URL- The tool is programmed to download the content located at the provided URL and return its content in markdown format
- The content is then forwarded to the MCP server
- Flow control is returned to the MCP client. We complete the journey with steps 11-14 depicted in the following picture.
- The MCP client adds a
toolResult
message to the conversation history inclding thetoolUseId
provided at step 4 and forwards it to Bedrock. Read these docs for more information abouttoolResult
syntax. - Bedrock now plans to use the result of the tool to compose its final response
- The response is sent back to the client which is programmed to yield back the control of the conversation flow to the user
- the user receives the response from the MCP client and the user is free to initiate a new flow
- Complete this tutorial showing how to create an MCP server in Python. At the end of the tutorial you should have a working MCP server providing two tools:
get_alerts
andget_weather
. This also includes installinguv
, a fast and secure Python runtime and package manager. - make sure you've exported your AWS credentials in your environment, so that they're available to
boto3
💡 For more information on how to do this, please refer to the AWS Boto3 documentation (Developer Guide > Credentials).
mcp-client
folder we're going to create now)
weather/
and create a new python projectmain.py
and create a new file called client.py
byuv
mcp
package to manage access to the MCP server session and of course a sprinkle of boto3
to add the Bedrock goodness.MCPClient
self.session
is the object mapping to the MCP session we're establishing. In this case we'll be usingstdio
, as we'll be using tools hosted on the same machineself.bedrock
creates an AWS SDK client that provides methods to interact with Amazon Bedrock's runtime APIs, allowing you to make API calls like converse to communicate with foundation models.self.exit_stack = AsyncExitStack()
creates a context manager that helps manage multiple async resources (like network connections and file handles) by automatically cleaning them up in reverse order when the program exits, similar to a stack of nestedasync with
statements but more flexible and programmatic. We're making use ofself.exit_stack
in the publiccleanup
method to cut loose ends.- The
connect_to_server
method establishes a bidirectional communication channel with a Python or Node.js script that implements MCP tools, using standard input/output (stdio) for message passing, and initializes a session that allows the client to discover and call the tools exposed by the server script.
_make_bedrock_request
method is a private helper that sends a request to Amazon Bedrock's Converse API, passing in the conversation history ( messages), available tools, and model configuration parameters (like token limit and temperature), to get a response from the foundation model for the next turn of conversation. We'll use this in a couple of different methodsprocess_query
method orchestrates the entire query processing flow:- Creates a message from the user's query
- Fetches available tools from the connected server
- Formats the tools into Bedrock's expected structure
- Makes a request to Bedrock with the query and tools
- Processes the response through potentially multiple turns of conversation (if tool use is needed)
- Returns the final response
_process_response
method initializes a conversation loop with a maximum of 10 turns (MAX_TURNS
), tracking responses infinal_text
.- When the model requests to use a tool, it processes the request by handling both thinking steps (text) and tool execution steps (toolUse).
- For tool usage, it calls the tool handler and makes a new request to Bedrock with the tool's results. Remember, we're hosting the tools locally in our MCP server.
- We also handle various stop conditions (max tokens, content filtering, stop sequence, end turn) by appending appropriate messages and breaking the loop.
- Finally, it joins all accumulated text with newlines and returns the complete conversation history.
_handle_tool_call
method executes a tool request by extracting the tool's name, arguments, and ID from the provided info.- It calls the tool through the
session
interface and awaits its result. - The method records both the tool request and its result in the conversation history. This is to let Bedrock know that we have had a conversation with somebody else, somewhere else (the tool running on your machine, I mean!)
- Finally, it returns a formatted message indicating which tool was called with what arguments.
chat_loop
method implements a simple interactive command-line interface that continuously accepts user input, processes queries through the system, and displays responses until the user types 'quit' or an error occurs.- The weather alert tool will help us fetching alerts for a state in the US
- prompt: "get me a summary of the weather alerts in California"
- The weather forecast tool will help us getting the forecast for a city in the US
- prompt: "get me a summary of the weather forecast for Buffalo, NY"
client.py
and don't forget to pass the path to where you're stored your tool.visit_webpage
function is a tool that fetches content from a given URL using HTTP GET requests. It converts the retrieved HTML content into a cleaner Markdown format, removing excessive line breaks and handling edge cases. The function includes comprehensive error handling for both network-related issues and unexpected errors, returning appropriate error messages when something goes wrong.validate_links
function takes a list of URLs and checks each one to verify if it's a valid, accessible webpage. It attempts to make HTTP GET requests to each URL, considering a link valid if the request succeeds and returns non-empty content. The function returns a list of URL-validity pairs, where each pair contains the URL and a boolean indicating whether the link is valid, with error handling for both network and general exceptions.- Dheeraj Mudgil - Sr. Solutions Architect, AWS Startups UKIR. Thank you for continuously providing kind and patient guidance on security and inspiring the architectural and flow diagrams in this article
- Heikki Tunkelo - Manager, Solutions Architecture, AWS Startups Nordics. Thanks for your bright remarks on organisational and business benefits in adopting MCP, and overall peer review of the article.
- João Galego - Head of AI at Critical Software and many other superimpositions. Thanks for your kind peer review. You keep insisting on the highest standards, even outside of Amazon.
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.