Build MCP tools for Amazon Bedrock AgentCore Gateway without the boilerplate.
Normally, exposing a Lambda function as an MCP gateway tool means wiring up tool schema JSON, uploading it to S3, registering a gateway target, handling the AgentCore context format, and routing multi-tool invocations — all before you write a single line of business logic.
This template eliminates that overhead. You write a decorated Python function, and make deploy handles the rest: schema generation, S3 upload, gateway registration, and Lambda deployment in one command.
This project uses the same @tool decorator from Strands Agents. If you already have tools running in-process on a Strands agent in AgentCore Runtime, you can copy them directly into this project as-is and deploy them as an out-of-process Lambda behind AgentCore Gateway, exposed via MCP - same decorator, same docstring, same code:
from strands import tool
@tool
def get_weather(location: str) -> dict:
"""Get the current weather for a location.
Args:
location: City name or zip code
"""
return {"location": location, "temperature": "72F", "condition": "sunny"}No schema files to write. The tool name, description, parameter types, and descriptions are all inferred from your code and docstring.
These commands setup a python virtual environment and install dependencies. This is optional if you want to do it another way.
make init
make installmake start# First time: creates Lambda + registers as gateway target
make create function=my-tools gateway_id=gw-abc123
# Test the deployed function
make invoke function=my-tools tool=get_weather
# After code changes: redeploys + updates gateway target
make deploy function=my-tools gateway_id=gw-abc123make delete function=my-toolsEdit tools.py and add a decorated function:
@tool
def search_products(query: str, limit: int = 10) -> dict:
"""Search the product catalog.
Args:
query: Search query
limit: Max results to return
"""
results = do_search(query, limit)
return {"results": results}That's it. The tool name, description, parameter types, required/optional, and parameter descriptions are all inferred from the function. Run make deploy to push the changes.
tools.py (define tools here — same @tool decorator as Strands)
|
├──> lambda_function.py (routes tool calls at runtime)
└──> generate_schema.py (exports tools.json at build time)
|
└──> tools.json → S3 → AgentCore Gateway
- One Lambda handles multiple tools, routed by tool name from the gateway context
- Tool schemas are auto-generated from your function signatures and docstrings
- The Makefile automates the full lifecycle: Lambda deploy, schema upload, and gateway registration
init run this once to initialize a new python project
install install project dependencies
start run local project
build package app for aws lambda - make build [packaging=zip]
role creates the lambda execution role
create create lambda + register as gateway target - make create function=X gateway_id=G
delete delete lambda - make delete function=X
deploy deploy code + update gateway target - make deploy function=X gateway_id=G
start-container run local project in container
push push container image to ECR - make push function=X
invoke invoke a tool on the lambda - make invoke function=X [tool=get_weather]
| Parameter | Default | Description |
|---|---|---|
arch |
arm64 |
arm64 or x86_64 |
function |
(required) | Lambda function name |
gateway_id |
(required for create/deploy) | AgentCore Gateway ID |
packaging |
container |
container or zip |
tool |
get_weather |
Tool name for make invoke |
make create and make deploy automatically:
- Generate
tools.jsonfrom your@tooldecorated functions - Create/reuse an S3 bucket (
agentcore-tools-{account}-{region}) - Upload the schema to
s3://{bucket}/{function}/tools.json - Register or update the gateway target
make startRuns main.py which invokes each tool with test parameters using a fake AgentCore context.
make start-container# In another terminal
curl -X POST "http://localhost:8080/2015-03-31/functions/function/invocations" \
-d '{"location": "Seattle, WA"}'Note: Container invocation doesn't pass client context, so the handler will raise an error about missing context. For full local testing with routing, use
make start.
| Environment Variable | Required | Description |
|---|---|---|
AWS_REGION |
Yes | AWS region for deployment |
| AWS credentials | Yes | Via environment, profile, or IAM role |
- Gateway expects raw JSON responses (not
{"statusCode": 200, ...}envelope)