Agentic AI AcademyAgentic AI Academy

AgentCore Gateway: The M×N Tool Problem

Turn APIs and Lambdas into MCP tools

Intermediate 13 minBuilder
What you'll be able to do
  • Explain the M×N integration problem and how Gateway collapses it to M+N by being a single MCP access point
  • Enumerate Gateway's six capabilities (Security Guard, Translation, Composition, Secure Credential Exchange, Semantic Tool Selection, Infrastructure Manager)
  • Distinguish the five core concepts: Gateway, Target, Authorizer, Credential Provider, and the auto-created Workload Identity
  • Differentiate the two gateway modes — Aggregation (MCP targets behind one tools/list) vs Direct/proxy (HTTP targets, path routing)
  • Identify the triple-underscore tool-naming convention `${target_name}___${tool_name}` and strip the prefix before dispatching downstream
  • Construct and recognize the Gateway MCP endpoint URL returned as `gatewayUrl`, and POST JSON-RPC over MCP to `/mcp`
At a glance

AgentCore Gateway is a fully managed service that turns APIs, Lambda functions, and existing services into MCP-compatible tools exposed to agents through a single endpoint. It solves the M×N integration problem — M agents wiring up to N tools — by becoming the one MCP access point every agent talks to. This lesson covers what Gateway is, its six capabilities, the five core concepts, the aggregation-vs-proxy split, the triple-underscore tool-naming gotcha, and the shape of the MCP endpoint URL.

  1. 1The M×N tool problem
  2. 2The six capabilities
  3. 3Five core concepts
  4. 4Two modes: Aggregation vs Direct/proxy
  5. 5The triple-underscore tool-naming gotcha
  6. 6Creating a Gateway in practice

The M×N tool problem

An agent is only as useful as the tools it can reach. The moment you go past a single demo, you hit an integration explosion. You have M agents (a support bot, an ops agent, a sales assistant) and N backends (an internal orders API, a couple of Lambda functions, Salesforce, a Jira instance). Wired naively, every agent has to learn how to talk to every backend — its auth scheme, its request shape, its error semantics. That's M×N integrations, and each one is bespoke glue you write, secure, and maintain.

AgentCore Gateway collapses M×N to M+N. It is a fully managed service that converts APIs, Lambda functions, and existing services into MCP-compatible tools exposed to agents through a single Gateway endpoint — per the AWS docs, "with just a few lines of code." Each backend is registered with the Gateway once (the N side). Each agent connects to the one Gateway endpoint as a standard MCP client (the M side). Agents no longer know or care that one tool is a Lambda, another is an OpenAPI service, and a third is Salesforce — they all arrive as MCP tools over one connection.

The AWS write-up frames Gateway as "the only solution that provides both comprehensive ingress and egress authentication in a fully-managed service." That phrase encodes the two halves of the problem Gateway owns:

  • Ingress (inbound)who is allowed to call the Gateway? Authenticating and authorizing the agent or caller hitting the MCP endpoint.
  • Egress (outbound)how does the Gateway authenticate to each backend? Injecting the right credential per target without that secret ever touching your agent code or the model's context.

We go deep on both auth directions in a later lesson. For now, hold the shape: many backends in, one MCP endpoint out, with auth managed on both sides.

Key insight

Why MCP, and why a single endpoint

MCP (Model Context Protocol) is the open standard your agent framework already speaks for tools. By translating every backend into MCP, Gateway lets any MCP-capable agent — Strands, LangGraph, the OpenAI Agents SDK, a raw MCP client — consume your entire tool catalog through one connection. Add a new tool to the Gateway and every agent gets it immediately, with zero code change on the agent side. That is the whole point of M+N over M×N.

The six capabilities

Gateway is more than a protocol shim. AWS breaks its job into six capabilities — read them as the list of plumbing you would otherwise hand-build per integration:

CapabilityWhat it does
Security GuardOAuth-based authorization on the inbound side — the bouncer deciding who may call the Gateway at all.
TranslationConverts MCP calls to/from the backend's native shape (MCP ↔ API / Lambda), so the agent only ever speaks MCP.
CompositionCombines many backends into a single MCP endpoint — the aggregation that makes M+N work.
Secure Credential ExchangeInjects the correct credential per tool on the outbound side, keeping secrets out of agent code.
Semantic Tool SelectionLets an agent search across thousands of tools for the relevant few instead of loading every schema.
Infrastructure ManagerRuns it all serverlessly with built-in observability — no servers to provision or scale.

On top of these, Gateway ships "1-click" built-in integration templates for common SaaS backends: Salesforce, Slack, Jira, Asana, and Zendesk. These let you stand up a working tool target for those services without authoring a schema by hand.

Map the capabilities back to the M×N problem: Translation and Composition are the M+N collapse; Security Guard and Secure Credential Exchange are the ingress/egress auth halves; Semantic Tool Selection keeps a large catalog usable; Infrastructure Manager is the "fully managed, serverless" promise.

Tip

Semantic Tool Selection is the scale story

A real enterprise Gateway can front hundreds or thousands of tools. Dumping every tool schema into the model's context would blow your context budget and degrade tool-choice accuracy. Semantic Tool Selection (covered in detail in the auth & search lesson) lets the agent query for relevant tools via a built-in search tool — but note it must be enabled AT gateway creation; you cannot turn it on later.

Five core concepts

Everything you configure in Gateway is one of five resources. Pin these names down — the rest of the Gateway module builds on them.

  • Gateway — the single MCP access point. Agents connect here; it exposes one MCP surface regardless of how many backends sit behind it.
  • Gateway Target — a backend the Gateway connects to. Targets come in two categories: MCP targets (aggregated — Lambda, OpenAPI, Smithy, API Gateway stages, remote MCP servers, the built-in SaaS templates) and HTTP targets (proxied — e.g. fronting an AgentCore Runtime agent as a tool).
  • Authorizer — the required inbound authorization config, exactly one per gateway. This is the ingress side: it decides who may invoke the Gateway. Options include OAuth/JWT, IAM SigV4, AUTHENTICATE_ONLY, or none (dev/test).
  • Credential Provider — the outbound credentials the Gateway uses to call a backend. This is the egress side, backed by AgentCore Identity.
  • Workload Identityauto-created when you create a gateway. You don't manage it directly; it's the agent/workload identity the Gateway operates under.

A useful mental model: the Authorizer is the bouncer at the door (inbound), the Credential Provider is the valet that fetches the right key for each backend (outbound), the Targets are the backends themselves, and the Gateway is the single front desk every agent talks to.

The MCP endpoint a Gateway exposes has a fixed shape:

text
https://{gateway-Id}.gateway.bedrock-agentcore.{Region}.amazonaws.com

This URL is returned to you as gatewayUrl from CreateGateway. Clients POST JSON-RPC over MCP Streamable HTTP to the /mcp path. The Gateway's ARN follows the standard pattern arn:${Partition}:bedrock-agentcore:${Region}:${Account}:gateway/${gateway-Id}.

Note

The Authorizer is mandatory at the resource level

Every gateway has exactly one Authorizer — there is no "unprotected" gateway in the object model. "No authorization" is itself an explicit authorizer choice meant for dev/test only. The gateway acts as an MCP resource server, which is why inbound auth is a first-class, required configuration rather than an afterthought.

Two modes: Aggregation vs Direct/proxy

A Gateway operates in one of two modes, determined by the kind of targets you attach. This distinction governs whether your tools get unified and searchable, or simply forwarded.

Aggregation mode (MCP targets). Multiple MCP targets are combined into a single virtual MCP server. The agent issues one tools/list call and gets back the union of tools across all aggregated targets. This is the mode that delivers Composition and Semantic Tool Selection. Lambda, OpenAPI, Smithy, API Gateway stages, remote MCP servers, and the built-in SaaS templates are all MCP targets.

Direct / proxy mode (HTTP targets). HTTP targets — for example, fronting a deployed AgentCore Runtime agent as a tool (agent-as-tool) — are proxied with path-based routing. There is no aggregation and no translation: the request is forwarded. HTTP targets are not searchable by semantic tool selection.

Aggregation (MCP targets)Direct / proxy (HTTP targets)
Target examplesLambda, OpenAPI, Smithy, API GW stage, remote MCP server, SaaS templatesAgentCore Runtime agent (agent-as-tool)
tools/listOne unified list across all targetsPath-routed, not aggregated
TranslationMCP ↔ backendNone (forwarded)
Semantic searchSupportedNot searchable
3LO / capability syncSupportedNot applicable

The practical takeaway: if you want a unified, searchable tool catalog, use MCP targets. Use the HTTP/proxy path specifically when you want to expose one Runtime agent to other agents as a callable tool.

Example

Concretely: a support agent's Gateway

A support agent might attach (1) a Lambda order-lookup target, (2) an OpenAPI target for the shipping API, and (3) the built-in Salesforce template — all MCP targets, aggregated into one tools/list the agent searches and calls. Separately, it might add an HTTP target fronting a deployed refund-policy Runtime agent, proxied as a single callable tool. The agent talks to one Gateway endpoint and never knows which is which.

The triple-underscore tool-naming gotcha

When Gateway aggregates targets, two different targets could expose tools with the same name. Gateway prevents collisions by namespacing every tool with its target name using a triple underscore:

text
${target_name}___${tool_name}

For example, a target named LambdaUsingSDK that exposes a tool get_order_tool appears to the agent — in tools/list and in tools/call — as:

text
LambdaUsingSDK___get_order_tool

Here is the gotcha that bites everyone: your downstream backend receives the prefixed name. When the Gateway dispatches the call to your Lambda, the tool name in the payload still carries the ${target_name}___ prefix. If your Lambda's router switches on the bare tool name (get_order_tool), it will fail to match. You must strip the ${target_name}___ prefix before dispatching downstream.

A minimal Lambda handler that does this correctly:

python
def handler(event, context):
    # Gateway passes the namespaced tool name, e.g. "LambdaUsingSDK___get_order_tool"
    tool_name = context.client_context.custom["bedrockAgentCoreToolName"]

    # Strip the "${target_name}___" prefix (split on the triple underscore).
    if "___" in tool_name:
        tool_name = tool_name.split("___", 1)[1]   # -> "get_order_tool"

    if tool_name == "get_order_tool":
        order_id = event["order_id"]
        return {"status": "shipped", "order_id": order_id}
    raise ValueError(f"Unknown tool: {tool_name}")

One more constraint to keep in mind: the namespaced tool name has a length ceiling of 256 characters (treat as [VOLATILE] — verify the live quotas page). Because the prefix eats into that budget, very long target and tool names can collide with the limit.

Watch out

Strip the prefix, don't hard-code the full name

Don't switch on the full LambdaUsingSDK___get_order_tool string in your backend — that couples your code to the Gateway target name, so renaming the target silently breaks every tool. Split on the triple underscore and route on the bare tool name. This is the single most common Gateway integration bug.

Creating a Gateway in practice

There are four ways to create a Gateway: the Console, the new AgentCore CLI, boto3 against the bedrock-agentcore-control client, and the Starter Toolkit GatewayClient. Here are the two you'll reach for most.

boto3 (control plane). You create the Gateway on the control plane, specifying its protocol, inbound authorizer, and (optionally) semantic search. Note that gatewayUrl comes back in the response:

python
import boto3

client = boto3.client("bedrock-agentcore-control")

gw = client.create_gateway(
    name="my-gateway",
    roleArn="arn:aws:iam::123456789012:role/my-gateway-service-role",
    protocolType="MCP",
    authorizerType="CUSTOM_JWT",                       # inbound: OAuth/JWT
    authorizerConfiguration={
        "customJWTAuthorizer": {
            "discoveryUrl": "https://cognito-idp.us-west-2.amazonaws.com/<pool>/.well-known/openid-configuration",
            "allowedClients": ["clientId"],
        }
    },
    protocolConfiguration={"mcp": {"searchType": "SEMANTIC"}},  # enables semantic tool search
)

print(gw["gatewayUrl"])
# -> https://{gateway-Id}.gateway.bedrock-agentcore.us-west-2.amazonaws.com

AgentCore CLI. The CLI wraps the same control plane with friendlier verbs. You add a gateway, then add targets to it, then deploy:

bash
# Create the gateway (NONE authorizer here is dev/test only)
agentcore add gateway --name TestGateway --authorizer-type NONE --runtimes MyGatewayAgent

# Add a Lambda MCP target with a tool schema
agentcore add gateway-target --name TestLambdaTarget --type lambda-function-arn \
  --lambda-arn <ARN> --tool-schema-file tools.json --gateway TestGateway

# Add an OpenAPI MCP target (each operationId becomes a tool)
agentcore add gateway-target --name MyOpenAPITarget --type open-api-schema \
  --schema path/to/openapi.json --outbound-auth none --gateway MyGateway

agentcore deploy

We build out the full range of targets — Lambda toolSchema, OpenAPI/operationId, Smithy, remote MCP servers, and Runtime-as-tool — in the next lesson. The point here is to see that a Gateway is just a control-plane resource you create once, and the MCP endpoint it hands back is the single door every agent walks through.

Watch out

Semantic search must be set at creation

protocolConfiguration.mcp.searchType = "SEMANTIC" can only be set when the Gateway is created. AWS is explicit: "you can't change its configuration to enable semantic search" afterward — you must recreate the Gateway. Decide up front whether your tool catalog is large enough to need it.

Try it: Stand up a Gateway and front a Lambda as an MCP tool

Goal: create a Gateway, attach a single Lambda target, and prove you understand the triple-underscore naming convention end to end. (Use us-east-1 or us-west-2; check that AgentCore is available in your region first.)

  1. Write a trivial tool Lambda. Create a Lambda whose handler reads the namespaced tool name from context.client_context.custom["bedrockAgentCoreToolName"], strips the ${target_name}___ prefix by splitting on the triple underscore, and routes on the bare name. Implement one tool, get_order, that returns {"status": "shipped", "order_id": <input>}.
  2. Author the tool schema. Create tools.json describing get_order (name, description, and an inputSchema with an order_id string property). This is the toolSchema Gateway needs for a Lambda MCP target.
  3. Create the Gateway. Using the AgentCore CLI, run agentcore add gateway --name OrdersGateway --authorizer-type NONE ... (NONE is dev/test only — fine for this lab). Then agentcore add gateway-target --name OrdersLambda --type lambda-function-arn --lambda-arn <ARN> --tool-schema-file tools.json --gateway OrdersGateway and agentcore deploy. Alternatively, do the equivalent with boto3 bedrock-agentcore-control create_gateway and capture the gatewayUrl from the response.
  4. Inspect the endpoint. Confirm the returned gatewayUrl matches the shape https://{gateway-Id}.gateway.bedrock-agentcore.{Region}.amazonaws.com.
  5. List the tools over MCP. POST a JSON-RPC tools/list request to {gatewayUrl}/mcp and confirm the tool appears as OrdersLambda___get_order — the triple-underscore prefix is the whole point.
  6. Call the tool. POST a tools/call with "name": "OrdersLambda___get_order" and arguments containing an order_id. Verify your Lambda strips the prefix, matches get_order, and returns the shipped status.
  7. Break it on purpose. Temporarily change your Lambda to compare against the full OrdersLambda___get_order string, redeploy, and confirm a target rename would break it — then revert to splitting on ___. Write two sentences on why routing on the bare name is the correct design.

Stretch: re-create the Gateway with protocolConfiguration.mcp.searchType = "SEMANTIC" and observe that you must set it at creation — you cannot enable it on the existing Gateway.

Key takeaways

  1. 1Gateway collapses the M×N integration problem (M agents × N tools) to M+N: register each backend once, and every agent connects to one managed MCP endpoint.
  2. 2It converts APIs, Lambda functions, and services into MCP-compatible tools, and is the managed home for both ingress (who may call) and egress (how it authenticates to backends) auth.
  3. 3Six capabilities: Security Guard, Translation, Composition, Secure Credential Exchange, Semantic Tool Selection, and Infrastructure Manager — plus 1-click templates for Salesforce, Slack, Jira, Asana, Zendesk.
  4. 4Five core concepts: Gateway (single MCP access point), Target (a backend), Authorizer (required inbound, one per gateway), Credential Provider (outbound), and an auto-created Workload Identity.
  5. 5Two modes: Aggregation (MCP targets → one virtual MCP server with a unified tools/list, searchable) vs Direct/proxy (HTTP targets like a Runtime agent, path-routed, no aggregation or search).
  6. 6Tools are namespaced as `${target_name}___${tool_name}` with a triple underscore; your downstream backend receives the prefixed name and must strip the prefix before dispatching.
  7. 7The MCP endpoint is `https://{gateway-Id}.gateway.bedrock-agentcore.{Region}.amazonaws.com`, returned as `gatewayUrl`; clients POST JSON-RPC over MCP Streamable HTTP to `/mcp`.

Quiz

Lock in what you learned

Check your understanding

0 / 4 answered

1.What problem is AgentCore Gateway primarily designed to solve?

2.Which set correctly lists Gateway's six capabilities?

3.A Gateway target named `OrdersLambda` exposes a tool `get_order`. Your Lambda's router checks `if tool_name == "get_order"` and never matches. Why?

4.Which statement about the two Gateway modes is correct?

Go deeper

Hand-picked sources to keep learning