Adding Lambda targets to your gateway - Amazon Bedrock AgentCore

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

Adding Lambda targets to your gateway

Lambda targets allow you to connect your gateway to AWS Lambda functions that implement your tools. This is useful when you want to execute custom code in response to tool invocations.

To add a Lambda target, you need:

  • A Lambda function ARN

  • A tool schema that defines the tools implemented by your Lambda function

  • Credential Provider configuration for how the Gateway authenticates with the Lambda function

Prerequisites

Before adding a Lambda target, ensure you have:

  • Created a Gateway: Follow the instructions in the "Set Up Gateway" guide to create your Gateway

  • Created a Lambda Function: Create a Lambda function that implements the tools you want to expose

  • Configured Permissions: Ensure your Gateway's execution role has permission to invoke the Lambda function

Configuring permissions

For Lambda function targets, your Gateway's execution role needs the lambda:InvokeFunction permission:

JSON
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AmazonBedrockAgentCoreGatewayLambdaProd", "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ "arn:aws:lambda:{{region}}:111122223333:function:[[functionName]]:*" ], "Condition": { "StringEquals": { "aws:ResourceAccount": "111122223333" } } } ] }

(Optional) Additionally, if your Lambda function was created in an account that's different from where the Gateway is being set up, it needs a resource-based policy that allows the Gateway's execution role to invoke it:

JSON
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/{{GatewayExecutionRoleName}}" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:{{region}}:111122223333:function:{{functionName}}" } ] }

You can add this policy using the AWS CLI:

aws lambda add-permission \ --function-name "YourLambdaFunction" \ --statement-id "GatewayInvoke" \ --action "lambda:InvokeFunction" \ --principal "arn:aws:iam::{{accountId}}:role/YourGatewayExecutionRole" \ --region {{region}}

Adding a Lambda target

You can add a Lambda target to your Gateway using one of the following methods:

CLI

The AgentCore CLI provides a simple way to add Lambda targets:

# Create a Gateway with Lambda target agentcore create_mcp_gateway_target \ --region us-east-1 \ --gateway-arn arn:aws:bedrock-agentcore:us-east-1:123456789012:gateway/gateway-id \ --gateway-url https://gateway-id.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp \ --role-arn arn:aws:iam::123456789012:role/BedrockAgentCoreGatewayRole \ --target-type lambda
Console
To add a target to an existing gateway
  1. Open the AgentCore console at https://console.aws.amazon.com/bedrock-agentcore/home#.

  2. Select the gateway to which you want to add a target.

  3. Choose the Targets tab.

  4. Choose Add target.

  5. Enter a Target name.

  6. (Optional) Provide an optional Target description.

  7. For Target type, choose Lambda function.

  8. For Lambda function, enter the ARN of your Lambda function.

  9. For Tool schema, choose to either provide the schema inline or reference an Amazon S3 location containing your tool schema.

  10. In the Outbound authentication section, configure authentication for accessing the Lambda function:

    1. For Authentication type, choose GATEWAY_IAM_ROLE.

  11. Choose Add target.

AgentCore SDK

You can add a Lambda target using the AgentCore SDK:

# 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" ] } } ] } }
Boto3

The following Python code shows how to add a Lambda target using boto3 (AWS SDK for Python):

import boto3 # Create the agentcore client agentcore_client = boto3.client('bedrock-agentcore-control') # Create a Lambda target target = agentcore_client.create_gateway_target( gatewayIdentifier="your-gateway-id", name="LambdaTarget", targetConfiguration={ "mcp": { "lambda": { "lambdaArn": "arn:aws:lambda:us-west-2:123456789012:function:YourLambdaFunction", "toolSchema": { "inlinePayload": [ { "name": "get_weather", "description": "Get weather for a location", "inputSchema": { "type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"], }, }, { "name": "get_time", "description": "Get time for a timezone", "inputSchema": { "type": "object", "properties": {"timezone": {"type": "string"}}, "required": ["timezone"], }, }, ] } } } }, credentialProviderConfigurations=[ { "credentialProviderType": "GATEWAY_IAM_ROLE" } ] )
API

Use the CreateGatewayTarget operation to add a Lambda target to your Gateway:

PUT /gateways/abc123def4/targets/ HTTP/1.1 Content-Type: application/json { "gatewayIdentifier": "abc123def4", "name": "LambdaTarget", "targetConfiguration": { "mcp": { "lambda": { "lambdaArn": "arn:aws:lambda:us-west-2:123456789012:function:YourLambdaFunction", "toolSchema": { "inlinePayload": [ { "name": "get_weather", "description": "Get weather for a location", "inputSchema": { "type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"] } } ] } } } }, "credentialProviderConfigurations": [ { "credentialProviderType": "GATEWAY_IAM_ROLE" } ] }

Lambda function schema

When creating a Lambda target without custom tools, the CLI auto-generates a default tool:

{ "name": "invoke_function", "description": "Invoke the Lambda function", "inputSchema": { "type": "object", "properties": {}, "required": [] } }

To specify custom tools, create a Lambda configuration file:

{ "arn": "arn:aws:lambda:us-west-2:123456789012:function:MyFunction", "tools": [ { "name": "process_data", "description": "Process input data", "inputSchema": { "type": "object", "properties": { "input": {"type": "string"} }, "required": ["input"] } } ] }

Each Tool in the toolSchema list should adhere to the following specification. You can optionally specify an outputSchema to provide more information to your agent about that tool.

{ "name": "string", "description": "string", # optional "inputSchema": { "type": "string", "properties": { "string (property name)": { "type": "string | number | object | array | boolean | integer", "items": { # optional, only applicable if type is list "type": "string | number | object | boolean | integer" }, "properties": {<same structure as this properties object>}, # optional, only applicable if type is object "required": [] } }, "required": [] }, "outputSchema": { # optional "type": "string", "properties": { "string (property name)": { "type": "string | number | object | array | boolean | integer", "items": { # optional, only applicable if type is list "type": "string | number | object | boolean | integer" }, "properties": {<same structure as this properties object>}, # optional, only applicable if type is object "required": [] } }, "required": [] } }

Adding multiple tools to a Lambda target

When you have multiple related tools that should be handled by the same Lambda function, you can define them in a single target. This approach simplifies management and allows your Lambda function to handle different types of requests.

AWS SDK

The following example shows how to create a Lambda target with multiple tools using the AWS SDK for Python (Boto3):

import boto3 # Create the AgentCore client agentcore_client = boto3.client('bedrock-agentcore-control') # Create a Lambda target with multiple tools agentcore_client.create_gateway_target( gatewayIdentifier="ProductGateway-AAAAA12345", name="ProductSearch", targetConfiguration={ "mcp": {"lambda": { "lambdaArn": "arn:aws:lambda:us-west-2:123456789012:function:product-search", "toolSchema": {"inlinePayload": [ { "name": "searchProducts", "description": "Searches for products based on keywords", "inputSchema": { "type": "object", "properties": { "keywords": { "type": "string", "description": "Search keywords" }, "category": { "type": "string", "description": "Product category" } }, "required": ["keywords"] } }, { "name": "getProductDetails", "description": "Gets detailed information about a specific product", "inputSchema": { "type": "object", "properties": { "productId": { "type": "string", "description": "Unique product identifier" } }, "required": ["productId"] } } ]} }} }, credentialProviderConfigurations=[{"credentialProviderType": "GATEWAY_IAM_ROLE"}] )

When your Lambda function is invoked, it can determine which tool is being called by examining the bedrockAgentCoreToolName property in the context object.

Using S3 for tool schemas

When you have a large number of tools or complex tool schemas, it might be more manageable to store your tool schemas in an Amazon S3 bucket. This approach allows you to maintain your tool definitions separately from your gateway configuration code.

AWS SDK

The following example shows how to create a Lambda target with a tool schema stored in S3:

import boto3 # Create the AgentCore client agentcore_client = boto3.client('bedrock-agentcore-control') # Create a Lambda target with a tool schema from S3 agentcore_client.create_gateway_target( gatewayIdentifier="ProductGateway-AAAAA12345", name="ProductSearch", targetConfiguration={ "mcp": {"lambda": { "lambdaArn": "arn:aws:lambda:us-west-2:123456789012:function:product-search", "toolSchema": {"s3": {"uri": "s3://my-schemas/product-tools.json"}} }} }, credentialProviderConfigurations=[{"credentialProviderType": "GATEWAY_IAM_ROLE"}] )

The S3 object should contain a JSON array of tool definitions following the same format as the inline payload. For example:

[ { "name": "searchProducts", "description": "Searches for products based on keywords", "inputSchema": { "type": "object", "properties": { "keywords": { "type": "string", "description": "Search keywords" }, "category": { "type": "string", "description": "Product category" } }, "required": ["keywords"] } }, { "name": "getProductDetails", "description": "Gets detailed information about a specific product", "inputSchema": { "type": "object", "properties": { "productId": { "type": "string", "description": "Unique product identifier" } }, "required": ["productId"] } } ]

To use S3 for tool schemas, ensure that the gateway's execution role has the necessary permissions to access the S3 bucket:

JSON
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::my-schemas/*" ] } ] }

Lambda function input format

When a gateway invokes a Lambda function, it passes an event object and a context object. The event object contains the request attributes mapped from MCP to your Lambda input. The context object contains useful information like the Gateway ID, Target ID, and tool name.

Event Object

Here's an example of the event object structure:

{ "keywords": "wireless headphones", "category": "electronics" }
Context Object

The context object contains metadata about the invocation, which your function can use to determine how to process the request:

# Access context properties in your Lambda function def lambda_handler(event, context): # Get the tool name from the context tool_name = context.client_context.custom['bedrockAgentCoreToolName'] # Get other context properties endpoint_id = context.client_context.custom['bedrockAgentCoreEndpointId'] target_id = context.client_context.custom['bedrockAgentCoreTargetId'] message_version = context.client_context.custom['bedrockAgentCoreMessageVersion'] session_id = context.client_context.custom['bedrockAgentCoreSessionId'] # Process the request based on the tool name if tool_name == 'searchProducts': # Handle searchProducts tool pass elif tool_name == 'getProductDetails': # Handle getProductDetails tool pass else: # Handle unknown tool pass

The context structure includes:

{ "bedrockAgentCoreMessageVersion": "1.0", "bedrockAgentCoreGatewayId": "string", "bedrockAgentCoreTargetId": "string", "bedrockAgentCoreToolName": "string" }

Limitations and considerations

When working with Lambda targets, be aware of the following limitations and considerations:

  • Tool name prefixes will need to be manually stripped off from the toolname in your AWS Lambda function

  • If you are using an existing AWS Lambda function and import it as a tool into the gateway, you will need to change the function code to account for a schema change for event and context objects

  • The Lambda function must return a valid JSON response that can be parsed by the gateway

  • Lambda function timeouts should be configured appropriately to handle the expected processing time of your tools

  • Consider implementing error handling in your Lambda function to provide meaningful error messages to the client