Connect: Amazon Bedrock AgentCore Gateway¶
Recipe · through our public MCP server · their docs checked 2026-10-30
AgentCore Gateway puts our server behind one MCP endpoint for your agents. The gateway authenticates callers on its side (inbound auth) and calls us with its own credential (outbound auth). It speaks MCP 2026-07-28, 2025-11-25, 2025-06-18 and 2025-03-26.
flowchart LR
AG["Agent"] -->|"inbound auth"| GW["AgentCore Gateway"]
GW -->|"API key: Authorization: Bearer …"| S["public_app /mcp"]
ID[("AgentCore Identity<br/>API key provider")] -.-> GW
Our side¶
def public_app(tools: Registry, host: str, agent_token: str, reviewer_token: str) -> Any:
"""REST at /, MCP at /mcp, one bearer check for both: for a host on the internet."""
from mcp.server.transport_security import TransportSecuritySettings
from agent_adapter.server import create_app
tokens = {
agent_token: Principal("hosted-agent"), # the token the remote framework sends
reviewer_token: Principal("reviewer@example.com", scopes=frozenset({APPROVER_SCOPE})),
}
security = TransportSecuritySettings(allowed_hosts=[host], allowed_origins=[f"https://{host}"])
return create_app(
tools,
authenticate=bearer_auth(tokens),
host="0.0.0.0", # a public bind: the public-host checks apply
allowed_hosts=[host], # REST: any other Host header gets 421
mcp_options={"transport_security": security}, # MCP: the same rule
)
hosted = registry.subset(tags=["hosted"]) # no confirm tools: hosted runtimes cannot resume them
Serve public_app(hosted, host, agent_token, reviewer_token).
Their side¶
- In AgentCore Identity, create an API key credential provider that holds our agent token (same account and Region as the gateway).
- Add an MCP server target (boto3
bedrock-agentcore-control):
control.create_gateway_target(
gatewayIdentifier=gateway_id,
name="shop-tools",
targetConfiguration={
"mcp": {"mcpServer": {"endpoint": "https://tools.example.com/mcp", "listingMode": "DEFAULT"}}
},
credentialProviderConfigurations=[
{
"credentialProviderType": "API_KEY",
"credentialProvider": {
"apiKeyCredentialProvider": {
"providerArn": api_key_provider_arn,
"credentialParameterName": "Authorization",
"credentialPrefix": "Bearer ",
"credentialLocation": "HEADER",
}
},
}
],
)
| Key | Meaning |
|---|---|
targetConfiguration.mcp.mcpServer.endpoint |
our /mcp URL (URL-encoded) |
listingMode |
DEFAULT: the gateway caches our tools/list; DYNAMIC: it asks us each time |
credentialProviderType: "API_KEY" |
outbound auth from an AgentCore Identity API key provider |
credentialParameterName, credentialPrefix, credentialLocation |
how the key is sent: header Authorization, value Bearer <token> |
SynchronizeGatewayTargets |
refresh the cached tool list after you change tools (DEFAULT mode) |
OAuth outbound (client credentials, authorization code, token exchange) also works when
bearer_auth is given an async verifier for your issuer's tokens.
Their side, OpenAPI target (alternative)¶
The gateway also imports an OpenAPI document, but refuses oneOf, anyOf and allOf and
spec-level security schemes. /openapi.json (3.1) has unions, so give it the
dialect="3.0-gateway" file instead (how):
3.0.3, no unions, only the invoke_<tool> operations, our server_url, no security.
control.create_gateway_target(
gatewayIdentifier=gateway_id,
name="shop-tools-rest",
targetConfiguration={"mcp": {"openApiSchema": {"inlinePayload": inline_payload}}},
credentialProviderConfigurations=[...], # the same API_KEY entry as step 2
)
| Key | Meaning |
|---|---|
openApiSchema.inlinePayload |
the document as JSON text (or s3 with a bucket URI) |
| tool names | the gateway uses each operationId: invoke_<tool> |
a 202 pending_approval |
a confirm tool runs only when a reviewer decides over REST, and the agent never sees that result: serve hosted here too |
Checklist¶
| Check | Why |
|---|---|
serve hosted |
the gateway does not send our resume keys back; a confirm tool would never run |
| every gateway caller shares the target's one token | so one principal: per-user runs need token exchange and a verifier |
call SynchronizeGatewayTargets after each tool change |
DEFAULT mode serves a cached list |
keep client_approval off |
the gateway passes 2026-07-28 requestState through unchecked, and no person sees a form |
| everything on the public-host checklist |
Sources¶
- MCP server targets: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-target-MCPservers.html
create_gateway_target(boto3): https://docs.aws.amazon.com/boto3/latest/reference/services/bedrock-agentcore-control/client/create_gateway_target.html- OpenAPI targets (limits, outbound auth): https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-schema-openapi.html
- Gateway concepts: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-core-concepts.html