Quick Start with creating and using a Gateway - Amazon Bedrock AgentCore

Amazon Bedrock AgentCore is in preview release and is subject to change.

Quick Start with creating and using a Gateway

This section provides quick start examples for creating a gateway and using it with different frameworks.

Prerequisites

Before creating a gateway, ensure you have the following prerequisites:

  • AWS account with permissions to create IAM roles, Lambda functions, and Cognito resources. You will also need permission to use Bedrock AgentCore APIs.

  • AWS credentials configured on your development environment

  • Python 3.6+ with boto3 installed

If you would rather create your roles, Lambda, and/or Cognito authorization server yourself, refer to the detailed setup instructions in Setting up a Amazon Bedrock AgentCore Gateway.

Install the key dependencies:

pip install boto3 pip install bedrock-agentcore-starter-toolkit pip install bedrock-agentcore pip install strands-agents

For detailed setup instructions, see Setting up a Amazon Bedrock AgentCore Gateway.

Creating a Gateway and attaching a Target

Now, let's dive in! Let's first create a Gateway and attach a Lambda Target:

from bedrock_agentcore_starter_toolkit.operations.gateway.client import GatewayClient import logging # setup the client client = GatewayClient(region_name="us-east-1") client.logger.setLevel(logging.DEBUG) # create cognito authorizer cognito_response = client.create_oauth_authorizer_with_cognito("TestGateway") # create the gateway gateway = client.create_mcp_gateway(authorizer_config=cognito_response["authorizer_config"]) # create a lambda target lambda_target = client.create_mcp_gateway_target(gateway=gateway, target_type="lambda")

You can customize your Gateway and Targets using your own role, Lambda functions, etc.:

# create the gateway. gateway = client.create_mcp_gateway( name=None, # the name of the Gateway - if you don't set one, one will be generated. role_arn=None, # the role arn that the Gateway will use - if you don't set one, one will be created. authorizer_config=cognito_response["authorizer_config"], # the OAuth authorizer details for authorizing callers to your Gateway (MCP only supports OAuth). enable_semantic_search=True, # enable semantic search. )
# create a lambda target. lambda_target = client.create_mcp_gateway_target( gateway=gateway, name=None, # the name of the Target - if you don't set one, one will be generated. target_type="lambda", # the type of the Target - you will see other target types later in the tutorial. target_payload=None, # the target details - set this to define your own lambda if you pre-created one. Otherwise leave this None and one will be created for you. credentials=None, # you will see later in the tutorial how to use this to connect to APIs using API keys and OAuth credentials. )

Example of target_payload for Lambda. Note this Lambda will be created for you if you don't provide a target_payload:

{ "lambdaArn": "<insert your lambda arn>", "toolSchema": { "inlinePayload": [ { "name": "get_weather", "description": "Get weather for a location", "inputSchema": { "type": "object", "properties": { "location": { "type": "string", "description": "the location e.g. seattle, wa" } }, "required": [ "location" ] } }, { "name": "get_time", "description": "Get time for a timezone", "inputSchema": { "type": "object", "properties": { "timezone": { "type": "string" } }, "required": [ "timezone" ] } } ] } }

OpenAPI and Smithy Targets

You can also add targets based on API specifications like Smithy and OpenAPI, making it possible for an Agent to get access to your APIs via Gateway.

Smithy API Model Targets

Let's add a target using the Smithy API model for DynamoDB (that is the default if no target_payload is specified):

# create a smithy target smithy_target = client.create_mcp_gateway_target(gateway=gateway, target_type="smithyModel")

Note: you can also use your own Smithy API model like this:

# create a smithy target smithy_target = client.create_mcp_gateway_target( gateway=gateway, target_type="smithyModel", target_payload={ "s3": { "uri": "<smithy model uri>" } } )

or you can even include an inline model:

# create a smithy target smithy_target = client.create_mcp_gateway_target( gateway=gateway, target_type="smithyModel", target_payload={ "inlinePayload": json.dumps(<smithy model>) } )

You can find Smithy API models for hundreds of AWS services here.

Open API Model Targets

Let's add the OpenAPI model for Brave search. You will need to sign up and get an API key to use Brave.

# create an openapi target w/ api key open_api_target = client.create_mcp_gateway_target( gateway=gateway, target_type="openApiSchema", target_payload={ "s3": { "uri": "s3://amazonbedrockagentcore-built-sampleschemas455e0815-oj7jujcd8xiu/brave-search-open-api.json" } }, credentials={ "api_key": "<api key>", "credential_location": "HEADER", "credential_parameter_name": "X-Subscription-Token" } )

Then let's add an OpenAPI w/ OAuth target:

open_api_with_oauth_target = client.create_mcp_gateway_target( gateway=gateway, target_type="openApiSchema", target_payload={ "s3": { "uri": "<to be updated>" } }, credentials={"oauth2_provider_config": { "customOauth2ProviderConfig": { "oauthDiscovery" : { "authorizationServerMetadata" : { "issuer" : "<endpoint>", "authorizationEndpoint" : "<endpoint>", "tokenEndpoint" : "<endpoint>" } }, "clientId" : "<client id>", "clientSecret" : "<client secret>" }}} )

Using the Gateway in an Agent

Now that we have setup a Gateway and Target, let's test it out! The following code sets up an interactive Strands agent with Amazon Bedrock:

from strands import Agent import logging from strands.models import BedrockModel from strands.tools.mcp.mcp_client import MCPClient from mcp.client.streamable_http import streamablehttp_client import os def create_streamable_http_transport(mcp_url: str, access_token: str): return streamablehttp_client(mcp_url, headers={"Authorization": f"Bearer {access_token}"}) def get_full_tools_list(client): more_tools = True tools = [] pagination_token = None while more_tools: tmp_tools = client.list_tools_sync(pagination_token=pagination_token) tools.extend(tmp_tools) if tmp_tools.pagination_token is None: more_tools = False else: more_tools = True pagination_token = tmp_tools.pagination_token return tools def run_agent(mcp_url: str, access_token: str): bedrockmodel = BedrockModel( inference_profile_id="anthropic.claude-3-7-sonnet-20250219-v1:0", temperature=0.7, streaming=True, ) mcp_client = MCPClient(lambda: create_streamable_http_transport(mcp_url, access_token)) with mcp_client: tools = get_full_tools_list(mcp_client) print(f"Found the following tools: {[tool.tool_name for tool in tools]}") agent = Agent(model=bedrockmodel,tools=tools) while True: user_input = input("\nThis is an interactive Strands Agent. Ask me something. When you're finished, say exit or quit: ") if user_input.lower() in ["exit", "quit", "bye"]: print("Goodbye!") break print("\nThinking...\n") agent(user_input) # get access token access_token = client.get_access_token_for_cognito(cognito_response["client_info"]) # Run your agent! run_agent(gateway["gatewayUrl"], access_token)

Let's run it! Why don't you try asking the agent for the weather? Note: in this example weather details and time details are hard-coded.