

# Use an AgentCore gateway
<a name="gateway-using"></a>

After [setting up your gateway with targets](gateway-building.md) , you can configure your application or agent to use the gateway through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) . The MCP provides a standardized way for agents to discover and invoke tools.

**Note**  
AgentCore Gateway supports the following MCP versions: \$1 2025-06-18 \$1 2025-03-26

You can use the following MCP operations with an AgentCore gateway:


| Operation | Description | 
| --- | --- | 
|  tools/call  |  Invokes a specific tool with the provided arguments  | 
|  tools/list  |  Lists all available tools provided by the gateway  | 

The following topics describe how to invoke your AgentCore gateway:

**Topics**
+ [Authorize and authenticate to an AgentCore gateway and gateway target](gateway-using-auth.md)
+ [List available tools in an AgentCore gateway](gateway-using-mcp-list.md)
+ [Call a tool in a AgentCore gateway](gateway-using-mcp-call.md)
+ [Search for tools in your AgentCore gateway with a natural language query](gateway-using-mcp-semantic-search.md)
+ [Create an agent that uses your AgentCore gateway](gateway-agent-integration.md)

# Authorize and authenticate to an AgentCore gateway and gateway target
<a name="gateway-using-auth"></a>

To invoke your gateway and gateway target, you’ll need to make sure that the following credentials that you set up while fulfilling the [prerequisites](gateway-prerequisites.md) are recognized during gateway invocation:
+  [Inbound authorization](gateway-inbound-auth.md) – Authorization and authentication to the gateway.
+  [Outbound authorization](gateway-outbound-auth.md) – Authorization and authentication to the gateway target.

To learn how to obtain and configure credentials, review the provider documentation for the methods that you choose.

The following sectiions provide examples of obtaining and configuring credentials for different use cases.

**Topics**
+ [Example: Authorization for the default gateway and target created by the AgentCore CLI](gateway-using-auth-ex-starter.md)
+ [Example: Authentication with an authorization code grant when invoking a gateway](gateway-using-auth-ex-3lo.md)

# Example: Authorization for the default gateway and target created by the AgentCore CLI
<a name="gateway-using-auth-ex-starter"></a>

If you used the AgentCore CLI to create a gateway and a Lambda target, the CLI configures JWT-based inbound authorization and IAM-based outbound authorization for you automatically.

**Note**  
If you invoke your gateway using `agentcore invoke` , the CLI handles authentication automatically. The steps below are only needed if you want to invoke the gateway programmatically (for example, using the AWS SDK or `curl` ).

For programmatic access, you’ll authorize with the following:
+  **Inbound authorization using JWT** – Obtain the access token from the Amazon Cognito authorization that was automatically set up for you and include it in the authorization header. See the example below to learn how to obtain the token.
+  **Outbound authorization using IAM** – The AgentCore CLI configures the following permissions for you, so you don’t need any additional setup:
  + Your gateway service role has permissions to invoke all functions in Lambda (provided by the [BedrockAgentCoreFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/BedrockAgentCoreFullAccess.html) managed policy).
  + The created Lambda function is configured with your gateway service role as a `Principal` that can invoke it.

You can obtain the access token created for your gateway by the AgentCore CLI with the help of Amazon Cognito by collecting the following information:
+  **Token endpoint** – Find at the **Discovery URL** in the authorizer configuration for the gateway. If you use the API, you can find the discovery URL by sending a [ListGateways](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_ListGateways.html) request or a [GetGateway](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_GetGateway.html) request for your gateway.
+  **Client ID** – Find in the Amazon Cognito user pool information. If you use the API, you can send a [ListUserPools](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUserPools.html) request or a [DescribeUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeUserPool.html) request for the user pool associated with your gateway.
+  **Client secret** – Find in the Amazon Cognito user pool app client information. If you use the API, you can send a [DescribeUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeUserPoolClient.html) request, specifying the client ID and user pool ID associated with your gateway.

First, collect these values with one of the following methods. Select one of the following methods:

**Example**  

1. Get the **token endpoint** :

   1. Open the AgentCore console at [https://console.aws.amazon.com/bedrock-agentcore/home\$1](https://console.aws.amazon.com/bedrock-agentcore/home#).

   1. From the left navigation pane, choose **Gateways**.

   1. In the **Gateways** section, select your gateway.

   1. In the **Inbound Identity** section, note the following values:
      +  **Allowed clients** – The client IDs that can access the gateway.
      +  **Discovery URL** – The format should be `https://cognito-idp.${Region}.amazonaws.com/${UserPoolId}/.well-known/openid-configuration` . Store the following values:
        +  `${UserPoolId}` – Extract from the Discovery URL.
        +  **Token endpoint** – Select the Discovery URL link and find the value in the `token_endpoint` field.

1. Get the **client ID** and **client secret** :

   1. Open the Amazon Cognito console at [https://console.aws.amazon.com/cognito](https://console.aws.amazon.com/cognito).

   1. From the left navigation pane, select **User pools**.

   1. Select the user pool ID associated with your gateway.

   1. From the left navigation pane, choose **App clients**.

   1. Select an app client whose **Client ID** matches the allowed clients for your token endpoint. Store the ID value.

   1. Under **Client secret** , select **Show client secret** and store that value.

1. Run the AgentCore `get-gateway` command in a terminal and specify your gateway ID in the `--gateway-identifier` argument, as in the following example:

   ```
   aws bedrock-agentcore-control get-gateway --gateway-identifier my-gateway-id
   ```

1. From the response, note the `discoveryUrl` from the `authorizerConfiguration` field:
   + Store the `${UserPoolId}` from the URL. The format should be `https://cognito-idp.${Region}.amazonaws.com/${UserPoolId}/.well-known/openid-configuration`.
   + Store the `allowedClients` values. These are the client IDs that can access the token endpoint.
   + Navigate to the `discoveryUrl` in a browser and store the `token_endpoint` value.

1. Run the Amazon Cognito `describe-user-pool-client` command in a terminal and specify the user pool ID in the `--user-pool-id` argument and an allowed client ID in the `--client-id` field, as in the following example:

   ```
   aws cognito-idp describe-user-pool-client --user-pool-id my-user-pool-id --client-id my-client-id
   ```

1. Store the `ClientSecret` value.

1. Run the following Python code to store the token endpoint, client ID, and client secret as variables:

   ```
   import requests
     import boto3
   
     # Initialize AWS clients
     agentcore_client = boto3.client("bedrock-agentcore-control")
     cognito_client = boto3.client("cognito-idp")
   
     # Replace with your actual gateway ID
     gateway_id = "my-gateway-id"
   
     # Get discovery URL and first allowed client
     auth_config = agentcore_client.get_gateway(gatewayIdentifier=gateway_id)["authorizerConfiguration"]["customJWTAuthorizer"]
     discovery_url, client_id = auth_config["discoveryUrl"], auth_config["allowedClients"][0]
   
     # Get token endpoint from discovery URL
     discovery_url_json = requests.get(discovery_url).json()
     token_endpoint, user_pool_id = discovery_url_json["token_endpoint"], discovery_url_json["issuer"].split("/")[-1]
   
     # Get client secret
     client_secret = cognito_client.describe_user_pool_client(
         UserPoolId=user_pool_id,
         ClientId=client_id
     )["UserPoolClient"]["ClientSecret"]
   ```

Second, use the values you gathered to access the token from the token endpoint. Select one of the following methods:

**Example**  

1. Run the following command in a terminal, replacing the token endpoint, client ID, and client secret values.

   ```
   curl --http1.1 -X POST ${TokenEndpoint} \
       -H "Content-Type: application/x-www-form-urlencoded" \
       -d "grant_type=client_credentials&client_id=${ClientId}&client_secret=${ClientSecret}"
   ```

   The token is in the `access_token` field of the response, while the `token_type` field should specify `Bearer`.

1. Run the following Python code to obtain your access token. The code assumes that you stored the `token_endpoint` , `client_id` , and `client_secret` values from the previous step:

   ```
   import requests
     import json
   
     def get_access_token(token_endpoint, client_id, client_secret):
         headers={
             "Content-Type": "application/x-www-form-urlencoded"
         }
   
         payload={
             "grant_type": "client_credentials",
             "client_id": client_id,
             "client_secret": client_secret
         }
   
         response = requests.post(token_endpoint, headers=headers, data=payload)
         return response.json()
   
     # Replace the argument values as necessary, if you didn't previously store them as these variables
     access_token_response = get_access_token(
         token_endpoint=token_endpoint,
         client_id=client_id,
         client_secret=client_secret
     )
   
     access_token = access_token_response["access_token"]
   ```

# Example: Authentication with an authorization code grant when invoking a gateway
<a name="gateway-using-auth-ex-3lo"></a>

If you set up your gateway target with an authorization code grant (for more information, see [OAuth authorization](gateway-building-adding-targets-authorization.md#gateway-building-adding-targets-authorization-oauth) ), the `defaultReturnUrl` that you specified when creating the gateway will be the link that the user’s browser redirects to after authentication.

You can use the `_meta` field in the `params` object of the request body to modify default configurations. With 3LO authentication, you map the `_meta` field to the following object:

```
{
    "aws.bedrock-agentcore.gateway/credentialProviderConfiguration": {
        "oauthcredentialProvider": {
            "returnUrl": "string",
            "forceAuthentication": bool
        }
    }
}
```

You can do the following:
+ To override the default return URL with a different one, specify a new `returnUrl`.
+ To remove the previous authentication from the token vault and return a new authorization URL when the request is made, set the `forceAuthentication` value to `true`.

For example, the following request would call the `LinkedIn3LO___gateUserInfo` tool through the gateway target, force the user to authenticate with a new authorization URL, and redirect the user to `https://your-public-domain.com/callback` after authentication:

```
{
  "jsonrpc": "2.0",
  "id": 24,
  "method": "tools/call",
  "params": {
    "name": "LinkedIn3LO___getUserInfo",
    "arguments": {},
    "_meta": {
        "aws.bedrock-agentcore.gateway/credentialProviderConfiguration": {
            "oauthCredentialProvider": {
                "returnUrl": "https://your-public-domain.com/callback",
                "forceAuthentication": true
            }
        }
    }
  }
}
```

# List available tools in an AgentCore gateway
<a name="gateway-using-mcp-list"></a>

To list all available tools that an AgentCore gateway provides, make a POST request to the gateway’s MCP endpoint and specify `tools/list` as the method in the request body:

```
POST /mcp HTTP/1.1
Host: ${GatewayEndpoint}
Content-Type: application/json
Authorization: ${Authorization header}

${RequestBody}
```

Replace the following values:
+  `${GatewayEndpoint}` – The URL of the gateway, as provided in the response of the [CreateGateway](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateGateway.html) API.
+  `${Authorization header}` – The authorization credentials from the identity provider when you set up [inbound authorization](gateway-inbound-auth.md).
+  `${RequestBody}` – The JSON payload of the request body, as specified in [Listing tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#listing-tools) in the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) . Include `tools/list` as the `method`.

**Note**  
For a list of optionally supported parameters for `tools/list` , see the `params` object in the request body at [Tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools) in the [Model Context Protocol documentation](https://modelcontextprotocol.io/specification/2025-06-18) . At the top of the page next to the search bar, you can select the MCP version whose documentation you want to view. Make sure that the version is one [supported by Amazon Bedrock AgentCore](gateway-using.md).

The response returns a list of available tools with their names, descriptions, and parameter schemas.

## Code samples for listing tools
<a name="gateway-using-mcp-list-examples"></a>

To see examples of listing available tools in the gateway, select one of the following methods:

**Example**  

1. 

   ```
   import requests
   import json
   
   def list_tools(gateway_url, access_token):
       headers = {
           "Content-Type": "application/json",
           "Authorization": f"Bearer {access_token}"
       }
   
       payload = {
           "jsonrpc": "2.0",
           "id": "list-tools-request",
           "method": "tools/list"
       }
   
       response = requests.post(gateway_url, headers=headers, json=payload)
       return response.json()
   
   # Example usage
   gateway_url = "https://${GatewayEndpoint}/mcp" # Replace with your actual gateway endpoint
   access_token = "${AccessToken}" # Replace with your actual access token
   tools = list_tools(gateway_url, access_token)
   print(json.dumps(tools, indent=2))
   ```

1. 

   ```
   import asyncio
   from mcp import ClientSession
   from mcp.client.streamable_http import streamablehttp_client
   
   async def execute_mcp(
       url,
       token,
       headers=None
   ):
       default_headers = {
           "Authorization": f"Bearer {token}"
       }
       headers = {**default_headers, **(headers or {})}
   
       async with streamablehttp_client(
          url=url,
          headers=headers,
       ) as (
           read_stream,
           write_stream,
           callA,
       ):
           async with ClientSession(read_stream, write_stream) as session:
               # 1. Perform initialization handshake
               print("Initializing MCP...")
               _init_response = await session.initialize()
               print(f"MCP Server Initialize successful! - {_init_response}")
   
               # 2. List available tools
               print("Listing tools...")
               cursor = True
               tools = []
               while cursor:
                   next_cursor = cursor
                   if type(cursor) == bool:
                       next_cursor = None
                   list_tools_response = await session.list_tools(next_cursor)
                   tools.extend(list_tools_response.tools)
                   cursor = list_tools_response.nextCursor
   
               tool_names = []
               if tools:
                   for tool in tools:
                       tool_names.append(tool.name)
               tool_names_string = "\n".join(tool_names)
               print(
                   f"List MCP tools. # of tools - {len(tools)}"
                   f"List of tools - \n{tool_names_string}\n"
               )
   
   async def main():
       url = "https://${GatewayEndpoint}/mcp"
       token = "your_bearer_token_here"
   
       # Optional additional headers
       additional_headers = {
           "Content-Type": "application/json",
       }
   
       await execute_mcp(
           url=url,
           token=token,
           headers=additional_headers
       )
   
   # Run the async function
   if __name__ == "__main__":
       asyncio.run(main())
   ```

1. 

   ```
   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):
       """
       List tools w/ support for pagination
       """
       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):
       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]}")
   
   run_agent(<MCP URL>, <Access token>)
   ```

1. 

   ```
   import asyncio
   
   from langchain_mcp_adapters.client import MultiServerMCPClient
   
   def list_tools(
       url,
       headers
   ):
       mcp_client = MultiServerMCPClient(
           {
               "agent": {
                   "transport": "streamable_http",
                   "url": url,
                   "headers": headers,
               }
           }
       )
       tools = asyncio.run(mcp_client.get_tools())
       tool_details = []
       tool_names = []
       for tool in tools:
           tool_names.append(f"{tool.name}")
           tool_detail = f"{tool.name} - {tool.description} \n"
   
           tool_properties = tool.args_schema.get('properties', {})
           properties = []
           for property_name, tool_property in tool_properties.items():
               properties.append(f"{property_name} - {tool_property.get('description', None)} \n")
           tool_details.append(f"{tool_detail}{"\n".join(properties)}")
   
       tool_details_string = "\n".join(tool_details)
       tool_names_string = "\n".join(tool_names)
       print(
           f"Langchain: List MCP tools. # of tools - {len(tools)}\n",
           f"Langchain: List of tool names - \n{tool_names_string}\n"
           f"Langchain: Details of tools - \n{tool_details_string}\n"
       )
   ```

**Note**  
If search is enabled on the gateway, then the search tool, `x_amz_bedrock_agentcore_search` will be listed first in the response.

# Call a tool in a AgentCore gateway
<a name="gateway-using-mcp-call"></a>

To call a specific tool, make a POST request to the gateway’s MCP endpoint and specify `tools/call` as the method in the request body, name of the tool, and the arguments:

```
POST /mcp HTTP/1.1
Host: ${GatewayEndpoint}
Content-Type: application/json
Authorization: ${Authorization header}

${RequestBody}
```

Replace the following values:
+  `${GatewayEndpoint}` – The URL of the gateway, as provided in the response of the [CreateGateway](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateGateway.html) API.
+  `${Authorization header}` – The authorization credentials from the identity provider when you set up [inbound authorization](gateway-inbound-auth.md).
+  `${RequestBody}` – The JSON payload of the request body, as specified in [Calling tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#calling-tools) in the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) . Include `tools/call` as the `method` and include the `name` of the tool and its `arguments`.

The response returns the content returned by the tool and associated metadata.

## Code samples for calling tools
<a name="gateway-using-mcp-call-examples"></a>

To see examples of listing available tools in the gateway, select one of the following methods:

**Example**  

1. The following curl request shows an example request to call a tool called `searchProducts` through a gateway with the ID `mygateway-abcdefghij`.

   ```
   curl -X POST \
     https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
       "jsonrpc": "2.0",
       "id": "invoke-tool-request",
       "method": "tools/call",
       "params": {
         "name": "searchProducts",
         "arguments": {
           "query": "wireless headphones",
           "category": "Electronics",
           "maxResults": 2,
           "priceRange": {
             "min": 50.00,
             "max": 200.00
           }
         }
       }
   }'
   ```

1. 

   ```
   import requests
   import json
   
   def call_tool(gateway_url, access_token, tool_name, arguments):
       headers = {
           "Content-Type": "application/json",
           "Authorization": f"Bearer {access_token}"
       }
   
       payload = {
           "jsonrpc": "2.0",
           "id": "call-tool-request",
           "method": "tools/call",
           "params": {
               "name": tool_name,
               "arguments": arguments
           }
       }
   
       response = requests.post(gateway_url, headers=headers, json=payload)
       return response.json()
   
   # Example usage
   gateway_url = "https://${GatewayEndpoint}/mcp" # Replace with your actual gateway endpoint
   access_token = "${AccessToken}" # Replace with your actual access token
   result = call_tool(
       gateway_url,
       access_token,
       "openapi-target-1___get_orders_byId",  # Replace with <{TargetId}__{ToolName}>
       {"orderId": "ORD-12345-67890", "customerId": "CUST-98765"}
   )
   print(json.dumps(result, indent=2))
   ```

1. 

   ```
   from mcp import ClientSession
   from mcp.client.streamable_http import streamablehttp_client
   import asyncio
   
   async def execute_mcp(
       url,
       token,
       tool_params,
       headers=None
   ):
       default_headers = {
           "Authorization": f"Bearer {token}"
       }
       headers = {**default_headers, **(headers or {})}
   
       async with streamablehttp_client(
          url=url,
          headers=headers,
       ) as (
           read_stream,
           write_stream,
           callA,
       ):
           async with ClientSession(read_stream, write_stream) as session:
               # 1. Perform initialization handshake
               print("Initializing MCP...")
               _init_response = await session.initialize()
               print(f"MCP Server Initialize successful! - {_init_response}")
   
               # 2. Call specific tool
               print(f"Calling tool: {tool_params['name']}")
               tool_response = await session.call_tool(
                   name=tool_params['name'],
                   arguments=tool_params['arguments']
               )
               print(f"Tool response: {tool_response}")
               return tool_response
   
   async def main():
       url = "https://${GatewayEndpoint}/mcp"
       token = "your_bearer_token_here"
       tool_params = {
           "name": "LambdaTarget___get_order_tool",
           "arguments": {
               "orderId": "order123"
           }
       }
       await execute_mcp(
           url=url,
           token=token,
           tool_params=tool_params
       )
   
   
   if __name__ == "__main__":
       asyncio.run(main())
   ```

1. NOTE: This is for invoking agent

   ```
   from strands.tools.mcp.mcp_client import MCPClient
   from mcp.client.streamable_http import streamablehttp_client
   
   def create_streamable_http_transport(mcp_url: str, access_token: str):
       return streamablehttp_client(mcp_url, headers={"Authorization": f"Bearer {access_token}"})
   
   def run_agent(mcp_url: str, access_token: str):
       mcp_client = MCPClient(lambda: create_streamable_http_transport(mcp_url, access_token))
   
       with mcp_client:
           result = mcp_client.call_tool_sync(
               tool_use_id="tool-123",  # A unique ID for the tool call
               name="openapi-target-1___get_orders",  # The name of the tool to invoke
               arguments={}  # A dictionary of arguments for the tool
           )
           print(result)
   
   url = {gatewayUrl}
   token = {AccessToken}
   run_agent(url, token)
   ```

1. NOTE: This is for invoking agent

   ```
   import asyncio
   
   from langgraph.prebuilt import create_react_agent
   
   def execute_agent(
       user_prompt,
       model_id,
       region,
       tools
   ):
       model = ChatBedrock(model_id=model_id, region_name=region)
   
       agent = create_react_agent(model, tools)
       _response = asyncio.run(agent.ainvoke({
           "messages": user_prompt
       }))
   
       _response = _response.get('messages', {})[1].content
       print(
           f"Invoke Langchain Agents Response"
           f"Response - \n{_response}\n"
       )
       return _response
   ```

## Errors
<a name="gateway-using-mcp-call-errors"></a>

The `tools/call` operation can return the following types of errors:
+ Errors returned as part of the HTTP status code:  
 **AuthenticationError**   
The request failed due to invalid authentication credentials.  
 **HTTP Status Code** : 401  
 **AuthorizationError**   
The caller does not have permission to invoke the tool.  
 **HTTP Status Code** : 403  
 **ResourceNotFoundError**   
The specified tool does not exist.  
 **HTTP Status Code** : 404  
 **ValidationError**   
The provided arguments do not conform to the tool’s input schema.  
 **HTTP Status Code** : 400  
 **ToolExecutionError**   
An error occurred while executing the tool.  
 **HTTP Status Code** : 500  
 **InternalServerError**   
An internal server error occurred.  
 **HTTP Status Code** : 500
+ MCP errors. For more information about these types of errors, [Error Handling](https://modelcontextprotocol.io/specification/2024-11-05/server/tools#error-handlinghttps://modelcontextprotocol.io/specification/2024-11-05/server/tools#error-handling) in the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) documentation.

# Search for tools in your AgentCore gateway with a natural language query
<a name="gateway-using-mcp-semantic-search"></a>

If you enabled semantic search for your gateway when you created it, you can call the `x_amz_bedrock_agentcore_search` tool to search for tools in your gateway with a natural language query. Semantic search is particularly useful when you have many tools and need to find the most appropriate ones for your use case. To learn how to enable semantic search during gateway creation, see [Create an Amazon Bedrock AgentCore gateway](gateway-create.md).

To search for a tool using this AgentCore tool, make the following POST request with the `tools/call` method to the gateway’s MCP endpoint:

```
POST /mcp HTTP/1.1
Host: ${GatewayEndpoint}
Content-Type: application/json
Authorization: ${Authorization header}

{
  "jsonrpc": "2.0",
  "id": "${RequestName}",
  "method": "tools/call",
  "params": {
    "name": "x_amz_bedrock_agentcore_search",
    "arguments": {
      "query": ${Query}
    }
  }
}
```

Replace the following values:
+  `${GatewayEndpoint}` – The URL of the gateway, as provided in the response of the [CreateGateway](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateGateway.html) API.
+  `${Authorization header}` – The authorization credentials from the identity provider when you set up [inbound authorization](gateway-inbound-auth.md).
+  `${RequestName}` – A name for the request.
+  `${Query}` – A natural language query to search for tools.

The response returns a list of tools that are relevant to the query.

## Code samples for tool searching
<a name="gateway-using-mcp-semantic-search-examples"></a>

To see examples of using natural language queries to find tools in the gateway, select one of the following methods:

**Example**  

1. 

   ```
   import requests
   import json
   
   def search_tools(gateway_url, access_token, query):
       headers = {
           "Content-Type": "application/json",
           "Authorization": f"Bearer {access_token}"
       }
   
       payload = {
           "jsonrpc": "2.0",
           "id": "search-tools-request",
           "method": "tools/call",
           "params": {
               "name": "x_amz_bedrock_agentcore_search",
               "arguments": {
                   "query": query
               }
           }
       }
   
       response = requests.post(gateway_url, headers=headers, json=payload)
       return response.json()
   
   # Example usage
   gateway_url = "https://${GatewayEndpoint}/mcp" # Replace with your actual gateway endpoint
   access_token = "${AccessToken}" # Replace with your actual access token
   results = search_tools(gateway_url, access_token, "find order information")
   print(json.dumps(results, indent=2))
   ```

1. 

   ```
   from mcp import ClientSession
   from mcp.client.streamable_http import streamablehttp_client
   import asyncio
   
   async def execute_mcp(
       url,
       token,
       tool_params,
       headers=None
   ):
       default_headers = {
           "Authorization": f"Bearer {token}"
       }
       headers = {**default_headers, **(headers or {})}
   
       async with streamablehttp_client(
          url=url,
          headers=headers,
       ) as (
           read_stream,
           write_stream,
           callA,
       ):
           async with ClientSession(read_stream, write_stream) as session:
               # 1. Perform initialization handshake
               print("Initializing MCP...")
               _init_response = await session.initialize()
               print(f"MCP Server Initialize successful! - {_init_response}")
   
               # 2. Call specific tool
               print(f"Calling tool: {tool_params['name']}")
               tool_response = await session.call_tool(
                   name=tool_params['name'],
                   arguments=tool_params['arguments']
               )
               print(f"Tool response: {tool_response}")
               return tool_response
   
   async def main():
       url = "https://${GatewayEndpoint}/mcp"
       token = "your_bearer_token_here"
       tool_params = {
           "name": "x_amz_bedrock_agentcore_search",
           "arguments": {
               "query": "How do I find order details?"
           }
       }
       await execute_mcp(
           url=url,
           token=token,
           tool_params=tool_params
       )
   
   
   if __name__ == "__main__":
       asyncio.run(main())
   ```

1. 

   ```
   from strands.tools.mcp.mcp_client import MCPClient
   from mcp.client.streamable_http import streamablehttp_client
   
   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):
       """
       List tools w/ support for pagination
       """
       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):
       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]}")
           result = mcp_client.call_tool_sync(
               tool_use_id="tool-123",  # A unique ID for the tool call
               name="x_amz_bedrock_agentcore_search",  # The name of the tool to invoke
               arguments={"query": "find order information"}  # A dictionary of arguments for the tool
           )
           print(result)
   
   url = {gatewayUrl}
   token = {AccessToken}
   run_agent(url, token)
   ```

1. 

   ```
   import asyncio
   
   from langchain_mcp_adapters.client import MultiServerMCPClient
   from langgraph.prebuilt import create_react_agent
   
   url = ""
   headers = {}
   
   def filter_search_tool(
   ):
       mcp_client = MultiServerMCPClient(
           {
               "agent": {
                   "transport": "streamable_http",
                   "url": url,
                   "headers": headers,
               }
           }
       )
       tools = asyncio.run(mcp_client.get_tools())
       builtin_search_tool = []
       for tool in tools:
           if tool.name == "x_amz_bedrock_agentcore_search":
               builtin_search_tool.append(tool)
       return builtin_search_tool
   
   def execute_agent(
       user_prompt,
       model_id,
       region,
       tools
   ):
       model = ChatBedrock(model_id=model_id, region_name=region)
   
       agent = create_react_agent(model, filter_search_tool())
       _response = asyncio.run(agent.ainvoke({
           "messages": user_prompt
       }))
   
       _response = _response.get('messages', {})[1].content
       print(
           f"Invoke Langchain Agents Response"
           f"Response - \n{_response}\n"
       )
       return _response
   ```

# Create an agent that uses your AgentCore gateway
<a name="gateway-agent-integration"></a>

After creating and testing your gateway, you can create and connect AI agents to your gateway. An agent connected to your gateway is able to call the tools in the gateway and use a [Amazon Bedrock model](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html) to respond to queries.

To learn how to create an agent, connect it to a gateway, and invoke it to answer queries, select one of the following methods:

**Example**  

1. 

   ```
   from strands import Agent
   from strands.models import BedrockModel
   from strands.tools.mcp.mcp_client import MCPClient
   from mcp.client.streamable_http import streamablehttp_client
   
   def _invoke_agent(
       bedrock_model,
       mcp_client,
       prompt
   ):
       with mcp_client:
           tools = mcp_client.list_tools_sync()
           agent = Agent(
               model=bedrock_model,
               tools=tools
           )
           return agent(prompt)
   
   def _create_streamable_http_transport(headers=None):
       url = {gatewayUrl}
       access_token = {AccessToken}
       headers = {**headers} if headers else {}
       headers["Authorization"] = f"Bearer {access_token}"
       return streamablehttp_client(
           url,
           headers=headers
       )
   
   def _get_bedrock_model(model_id):
       return BedrockModel(
           inference_profile_id=model_id,
           temperature=0.0,
           streaming=True,
      )
   
   mcp_client = MCPClient(_create_streamable_http_transport)
   
   if __name__ == "__main__":
       user_prompt = "What orders do I have?"
       _response = _invoke_agent(
           bedrock_model=_get_bedrock_model("us.anthropic.claude-sonnet-4-20250514-v1:0"),
           mcp_client=mcp_client,
           prompt=user_prompt
       )
       print(_response)
   ```

1. 

   ```
   from mcp import ClientSession
   from mcp.client.streamable_http import streamablehttp_client
   
   from langgraph.prebuilt import create_react_agent
   from langchain_mcp_adapters.tools import load_mcp_tools
   
   # Replace with actual values and the Amazon Bedrock model of your choice
   gateway_url = "${GatewayUrl}"
   access_token = "${AccessToken}"
   model = ChatBedrock(model_id="anthropic.claude-3-sonnet-20240229-v1:0", region_name="us-west-2")
   
   async with streamablehttp_client(gateway_url, headers={"Authorization": f"Bearer {access_token}"}) as (read, write, _):
       async with ClientSession(read, write) as session:
           # Initialize the connection
           await session.initialize()
   
           # Get tools
           tools = await load_mcp_tools(session)
           agent = create_react_agent(model, tools)
           math_response = await agent.ainvoke({"messages": "what's (3 + 5) x 12?"})
   ```

1. 

   ```
   #!/bin/bash
   # Script to add MCP server to Claude
   
   # Server configuration
   SERVER_NAME=${ServerName} # Write your server name
   GATEWAY_MCP_SERVER_URL=${GatewayUrl} # The gateway MCP URL
   AUTH_TOKEN=${AuthToken} # Claude authentication token
   
   echo "Adding MCP server to Claude..."
   echo "Server Name: $SERVER_NAME"
   echo "Server URL: $SERVER_URL"
   echo ""
   
   # Add the MCP server
   claude mcp add "$SERVER_NAME" "$GATEWAY_MCP_SERVER_URL" \
     --transport http \
     --header "Authorization: Bearer $AUTH_TOKEN"
   
   # Check if the command was successful
   if [ $? -eq 0 ]; then
       echo "MCP server added successfully!"
       echo ""
       echo "You can now check mcp server health with: claude mcp list"
   else
       echo "Failed to add MCP server"
       exit 1
   fi
   ```