"| Tutorial components | Creating and using Lambda-backed AgentCore Gateway from Strands Agent |\n",
"| Tutorial vertical | Cross-vertical |\n",
"| Example complexity | Easy |\n",
"| SDK used | Amazon BedrockAgentCore Python SDK and boto3 "
]
},
{
"cell_type": "markdown",
"id": "61187ab7",
"metadata": {},
"source": [
"### Tutorial Architecture\n",
"Amazon Bedrock AgentCore Gateway provides unified connectivity between agents and the tools and resources they need to interact with. Gateway plays multiple roles in this connectivity layer:\n",
"\n",
"1. **Security Guard**: Gateway manages OAuth authorization to ensure only valid users / agents access tools / resources.\n",
"2. **Translator**: Gateway translates agent requests made using popular protocols like the Model Context Protocol (MCP) into API requests and Lambda invocations. This means developers don’t need to host servers, manage protocol integration, version support, version patching, etc.\n",
"3. **Composer**: Gateway enables developers to seamlessly combine multiple APIs, functions, and tools into a single MCP endpoint that an agent can use.\n",
"4. **Keychain**: Gateway handles the injection of the right credentials to use with the right tool, ensuring that agents can seamlessly leverage tools that require different sets of credentials. \n",
"5. **Researcher**: Gateway enables agents to search across all of their tools to find only the ones that are best for a given context or question. This allows agents to make use of 1000s of tools instead of just a handful. It also minimizes the set of tools that need to be provided in an agent’s LLM prompt, reducing latency and cost. \n",
"6. **Infrastructure Manager**: Gateway is completely serverless, and comes with built-in observability and auditing, alleviating the need for developers to manage additional infrastructure to integrate their agents and tools. \n",
"\n",
"\n",
"\n",
"### Tutorial Key Features\n",
"\n",
"* Creating Amazon Bedrock AgentCore Gateways with AWS Lambda-backed targets\n",
"* Using AgentCore Gateway semantic search \n",
"* Using Strands Agents to show how AgentCore Gateway search improves latency"
]
},
{
"cell_type": "markdown",
"id": "fa1feb54",
"metadata": {},
"source": [
"## Prerequisites\n",
"\n",
"To execute this tutorial you will need:\n",
"* Python 3.10+\n",
"* AWS credentials\n",
"* Amazon Bedrock AgentCore SDK\n",
"* Strands Agents"
]
},
{
"cell_type": "markdown",
"id": "fb01ea0d",
"metadata": {},
"source": [
"## AgentCore Gateway helps solve the challenge of MCP servers that have large numbers of tools\n",
"In a typical enterprise setting, agent builders encounter MCP servers that have hundreds or even thousands\n",
"of MCP tools. This volume of tools poses challenges for AI agents, including poor tool selection accuracy, \n",
"increased cost, and higher latency driven by higher token usage from excessive tool metadata.\n",
"This can happen when connecting your agents to third party services (e.g., Zendesk, Salesforce,\n",
"Slack, JIRA, ...), or to existing enterprise REST services. \n",
"AgentCore Gateway provides a built in semantic search across tools, \n",
"which improves agent latency, cost, and accuracy, while still giving those agents the tools they need. \n",
"Depending on your use case, LLM model, and agent framework, you can see up to 3x better latency by keeping\n",
"an agent focused on relevant tools versus providing the full set of hundreds of tools from a typical MCP Server.\n",
"\n",
"\n",
"\n",
"## What you will learn in this notebook\n",
"In this notebook, we provide a tutorial for AgentCore Gateway search. By the end of this step-by-step tutorial, you\n",
"will understand:\n",
"\n",
"- How to use AgentCore Gateway's built-in search tool to quickly find relevant tools \n",
"- How to integrate tool search results into Strands Agents for improved latency and reduced cost\n",
"\n",
"## Overview of the notebook structure\n",
"The notebook is structured with the following sections:\n",
"\n",
"1. Understanding fundamentals of AgentCore Gateway Search\n",
"2. Preparing the notebook environment\n",
"3. Setting up a Gateway that has hundreds of tools\n",
"4. Searching for tools from a Gateway\n",
"5. Using Strands Agents with an MCP server that has many tools\n",
"6. Adding tool search results to a Strands Agent\n",
"7. Showing 3x latency improvement by using tool search"
]
},
{
"cell_type": "markdown",
"id": "06b7852f",
"metadata": {},
"source": [
"# Understanding fundamentals of AgentCore Gateway Search\n",
"\n",
"When you create an AgentCore Gateway, you have the option to indicate that you want Search enabled.\n",
"For Gateways with search enabled, three things happen:\n",
"\n",
"1. **Vector store is created**. The Gateway service automatically creates a serverless fully-managed vector store for your new Gateway. This enables a full semantic search across your Gateway tools. \n",
"3. **Vector store is populated**. As you add Gateway Targets to your Gateway, the service automatically uses embeddings behind the scenes to populate the vector store based on the tools from the new Target. The tool metadata comes from the JSON defintions of your tools or the OpenAPI Schema specification for your REST services targets.\n",
"2. **Search tool (MCP based) is provided**. In addition to all of your user defined tools (from AWS Lambda targets or REST services), the Gateway gets one additional MCP tool that provides semantic search. It is named `x-amz-bedrock-agentcore-search`. The prefix ensures there are no name clashes with your user-defined tools. We may add more tools like that in the future as well. The search tool has a single argument called `query`. When the search tool is invoked, the Gateway service performs a semantic search using that query, matching it against available tool metadata (names, descriptions, input and output schema), and returns the most relevant tools in descending order of relevance."
"Get our boto3 client for the AgentCore control plane API."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c2eafe7c",
"metadata": {},
"outputs": [],
"source": [
"session = boto3.Session()\n",
"agentcore_client = session.client(\n",
" \"bedrock-agentcore-control\",\n",
")"
]
},
{
"cell_type": "markdown",
"id": "eb9fec29",
"metadata": {},
"source": [
"# Setting up a Gateway that has hundreds of tools\n",
"\n",
"AgentCore Gateway provides a secure and scalable way to expose a curated set of existing APIs\n",
"as MCP tools for your agents. In a production setting, your Gateway resources would be created\n",
"using infrastructure as code with tools like CloudFormation, CDK, or Terraform. In this tutorial,\n",
"we use the boto3 control plane APIs directly, so that you can understand the resources and APIs more effectively.\n",
"This will help you more easily get started building and using your own gateways, and making more powerful\n",
"and secure agents.\n",
"\n",
"At a high level, the steps for setting up your Gateway are:\n",
"\n",
"1. Define what identity providers and credential providers you are using for inbound (agents calling Gateways) and outbound (Gateways calling tools) security.\n",
"2. Create the Gateway using `create_gateway`.\n",
"3. Add Gateway Targets using `create_gateway_target`, to expose MCP tools that will be implemented in AWS Lambda or in existing RESTful services.\n",
"\n",
"In this tutorial, we will use Amazon Cognito as the identity provider (IdP), AWS Lambda functions as targets, and AWS IAM for outbound authentication. The same concepts demonstrated in this tutorial still apply when using other IdP's or other target types."
]
},
{
"cell_type": "markdown",
"id": "d896e613",
"metadata": {},
"source": [
"### Creating Amazon Cognito resources"
]
},
{
"cell_type": "markdown",
"id": "bb02989f",
"metadata": {},
"source": [
"In this tutorial, we assume you have already created the following resources and have set up corresponding environment variables:\n",
"\n",
"- IAM role for AWS Lambda execution (`gateway_lambda_iam_role`)\n",
"- AWS Lambda function for your simple math tools (`calc_lambda_arn`)\n",
"- AWS Lambda function for your restaurant reservation tool (`restaurant_lambda_arn`)\n",
"- Amazon Cognito user pools, giving you a client id (`cognito_client_id`) and a discovery URL (`cognito_discovery_url`)"
]
},
{
"cell_type": "markdown",
"id": "c9cb9eb5",
"metadata": {},
"source": [
"Lets take a look at the JSON tool metadata for the restaurant API. Note that if we were integrating with existing REST services, the API specs would be provided using OpenAPI Schema instead."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e953add5",
"metadata": {},
"outputs": [],
"source": [
"with open(\"./restaurant/restaurant-api.json\") as f:\n",
" data = json.load(f)\n",
"print(json.dumps(data, indent=4))"
]
},
{
"cell_type": "markdown",
"id": "a0758917",
"metadata": {},
"source": [
"Here are the simple calculator APIs."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef1a47e2",
"metadata": {},
"outputs": [],
"source": [
"with open(\"./calc/calc-api.json\") as f:\n",
" data = json.load(f)[0:3]\n",
"print(json.dumps(data, indent=4))"
]
},
{
"cell_type": "markdown",
"id": "414b7a8a",
"metadata": {},
"source": [
"Here is the AWS Lambda function implementation for the calculator tools."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "48160295",
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import display, Code\n",
"\n",
"with open(\"./calc/lambda_function_code.py\", \"r\") as f:\n",
"print(f\"RestaurantTarget created with id: {restaurantTargetId} on gateway: {gatewayId}\")"
]
},
{
"cell_type": "markdown",
"id": "4da14900",
"metadata": {},
"source": [
"Here we'll add a second target, this time with a Lambda that implements 4 basic tools (add, subtract,\n",
"multiply, divide), and a set of 75 generated tool definitions for investment management (trading, credit research, quantitative analysis, portfolio management). The investment management tool definitions are not \n",
"actually implemented in the Lambda function. We are only adding them to demonstrate a large volume of tools."
" description=\"A special tool that returns a trimmed down list of tools given a context. Use this tool only when there are many tools available and you want to get a subset that matches the provided context.\",\n",
" inputSchema={\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"query\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"search query to use for finding tools\",\n",
"Notice the latency improvement. This example using a subset of tools from Gateway search is significantly faster than\n",
"agent invocation when depending on hundreds of tools."
]
},
{
"cell_type": "markdown",
"id": "78c1e64e",
"metadata": {},
"source": [
"# Showing 3x latency improvement by using tool search"
]
},
{
"cell_type": "markdown",
"id": "1bc164be",
"metadata": {},
"source": [
"Now that we know how to use Gateway MCP tools from a Strands agent, and we know how to search for tools and\n",
"add them to an agent, lets show the power of search. We'll highlight the significant latency reduction\n",
"and input token usage that can be delivered.\n",
"\n",
"To demonstrate the latency and token reductions, we compare 2 approaches side by side:\n",
"\n",
"1. **Without search**. We add the full set of MCP tools that the MCP server exposes (300+ in our case) to our agent and let the agent do its tool selection and invocation accordingly.\n",
"2. **Using search**. In the second approach, we do a search based on the topic at hand, and only send in the most relevant tools to the agent. To prove the point, we use two different topics: math (adding numbers), and food (booking a restaurant reservation), each requiring a different set of tools.\n",
"\n",
"To normalize the latency distribution and get a meaningful comparison, we perform multiple iterations of\n",
"each approach. Also, to avoid overstating the gains, when doing the search approach, we include not only the\n",
"latency of the agent invocation, but also the latency of performing the tool search. For each \n",
"iteration, we hand the agent two tasks: \n",
"\n",
"1. Math task - add 2 numbers \n",
"2. Food task - book a restaurant reservation\n",
"\n",
"The results below demonstrate the benefits, highlighting 3x latency reduction, and even greater reduction in\n",
"input token usage. Note that while token usage savings translate to cost savings, that may not be as impactful due to\n",
"the relatively lower cost of input tokens (for many model providers, input tokens are much lest costly). Even so, for \n",
"large scale agent deployment, even input token usage costs can add up, so dynamic search can help reduce \n",
"agent runtime costs as well."
]
},
{
"cell_type": "markdown",
"id": "e24ad450",
"metadata": {},
"source": [
"#### Measure latency and token usage for agent using the entire set of MCP tools"
"#### Compare results, higlighting benefits of search"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eef22580",
"metadata": {},
"outputs": [],
"source": [
"print(\n",
" f\"\\n\\nLatency without search: {full_elapsed_time:.1f}s, using search: {light_elapsed_time:.1f}s\"\n",
")\n",
"print(f\"Tokens without search: {full_tokens:,d}, using search: {light_tokens:,d}\")"
]
},
{
"cell_type": "markdown",
"id": "a7a0d35e",
"metadata": {},
"source": [
"# Conclusion\n",
"In this tutorial, you have learned about Amazon Bedrock AgentCore Gateway and its built-in \n",
"fully managed semantic search capability. You have seen the following:\n",
"\n",
"- how to create a gateway with semantic search enabled\n",
"- how to add multiple gateway targets to surface 300+ MCP tools from a single endpoint\n",
"- how to list the tools on your gateway using 3 different approaches\n",
"- how to use the built-in semantic search tool to find relevant tools\n",
"- how to integrate search with your Strands Agent\n",
"- how to compare performance of an agent using a server with hundreds of tools versus one that uses semantic search to narrow tools to a specific topic\n",
"\n",
"AgentCore Gateway search is helpful for more advanced use cases as well. By offering the search as a native\n",
"MCP tool and not just a control plane API, you can imagine giving your agents more autonomy to discover new\n",
"MCP servers, and find new capabilities at runtime leading to breakthroughs in solving more challenging problems.\n",
"In addition, search is an important foundation for MCP registries and supporting agent developers as they \n",
"design and build new agents."
]
},
{
"cell_type": "markdown",
"id": "3c569fc6",
"metadata": {},
"source": [
"# Cleaning up resources"
]
},
{
"cell_type": "markdown",
"id": "8c51ae00",
"metadata": {},
"source": [
"First let's define some helper functions for cleaning up AgentCore Gateway resources."