AgentCore CLI in Practice — Connect External MCP Servers via Gateway
Table of Contents
Introduction
Part 1 covered the basic lifecycle, Part 2 covered Memory persistence. This time we connect an external MCP server to an agent using Gateway.
AgentCore Gateway acts as an MCP-compatible proxy that handles request routing, authentication, and tool discovery between agents and backend tools. The agent only needs to know the Gateway URL — it doesn't need to know the details of the MCP servers or APIs behind it.
This article registers an external MCP server (Exa AI web search) as a Gateway target and verifies that the agent can call tools through the Gateway. See the CLI Gateway docs and configuration reference for the full spec.
AgentCore CLI is in Public Preview (v0.3.0-preview). Commands, options, and generated templates may change before GA. This article reflects behavior as of March 2026.
Prerequisites
- Environment from Part 1 (Node.js 20+, uv, AWS CLI, AgentCore CLI v0.3.0-preview)
- An AWS account in a supported AgentCore region
Gateway Overview
Five target types are available: mcp-server (external MCP server), api-gateway (API Gateway REST API), open-api-schema (OpenAPI spec), smithy-model (Smithy model), and lambda-function-arn (Lambda function). This article uses the simplest type: mcp-server. See the CLI docs for details on other types.
Project Setup
When using Gateway, the order of project setup is critical. As described in the CLI docs, setting up the Gateway and targets before adding the agent causes the Gateway client code to be auto-generated. Reverse order requires manual integration.
1. agentcore create --no-agent # Create project without agent
2. agentcore add gateway # Add Gateway
3. agentcore add gateway-target # Add target
4. agentcore add agent # Add agent (auto-wired to Gateway)
5. agentcore deploy # DeployStep 1: Create Project Without Agent
agentcore create --name AgentCoreGwTest --no-agent --skip-git
cd AgentCoreGwTestStep 2: Add Gateway
agentcore add gateway --name my-gateway --json{"success": true, "gatewayName": "my-gateway"}Gateway configuration is stored in agentcore/mcp.json, not agentcore.json. This is a separate config file dedicated to Gateways.
{
"agentCoreGateways": [
{
"name": "my-gateway",
"description": "Gateway for my-gateway",
"targets": [],
"authorizerType": "NONE",
"enableSemanticSearch": true,
"exceptionLevel": "NONE"
}
]
}authorizerType: "NONE" means no inbound authentication (for dev/test). Use AWS_IAM or CUSTOM_JWT in production.
Step 3: Add Gateway Target
We use Exa AI's web search as the external MCP server. Exa AI provides a public MCP endpoint that requires no authentication.
agentcore add gateway-target \
--type mcp-server \
--name exa-search \
--endpoint https://mcp.exa.ai/mcp \
--gateway my-gateway \
--json{"success": true, "toolName": "exa-search"}Step 4: Add Agent
Add the agent after Gateway setup. With --no-agent projects, --language and --memory must be specified explicitly.
agentcore add agent \
--name GwAgent \
--framework Strands \
--model-provider Bedrock \
--language Python \
--memory none \
--json{"success": true, "agentName": "GwAgent"}Auto-Generated Gateway Client Code
Because the agent was added after Gateway setup, mcp_client/client.py contains Gateway client code instead of the default MCP client.
import os
import logging
from mcp.client.streamable_http import streamablehttp_client
from strands.tools.mcp.mcp_client import MCPClient
logger = logging.getLogger(__name__)
def get_my_gateway_mcp_client() -> MCPClient | None:
"""Returns an MCP Client connected to the my-gateway gateway."""
url = os.environ.get("AGENTCORE_GATEWAY_MY_GATEWAY_URL")
if not url:
logger.warning("AGENTCORE_GATEWAY_MY_GATEWAY_URL not set — my-gateway gateway tools unavailable")
return None
return MCPClient(lambda: streamablehttp_client(url))
def get_all_gateway_mcp_clients() -> list[MCPClient]:
"""Returns MCP clients for all configured gateways."""
clients = []
client = get_my_gateway_mcp_client()
if client:
clients.append(client)
return clientsKey points:
- The Gateway URL comes from
AGENTCORE_GATEWAY_MY_GATEWAY_URL. The gateway namemy-gatewayis converted to uppercase with underscores (MY_GATEWAY) - Returns
Noneif the env var is not set (e.g., local dev before first deploy) get_all_gateway_mcp_clients()aggregates clients for all configured Gateways
In main.py, get_all_gateway_mcp_clients() replaces the default get_streamable_http_mcp_client() from Part 1.
from mcp_client.client import get_all_gateway_mcp_clients
# ...
mcp_clients = get_all_gateway_mcp_clients()Deploying to AWS
Configure Deployment Target
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
cat > agentcore/aws-targets.json << EOF
[
{
"name": "default",
"description": "Tokyo (ap-northeast-1)",
"account": "${ACCOUNT_ID}",
"region": "ap-northeast-1"
}
]
EOFDeploy
agentcore deploy -yGateway deployment happens in a separate phase from CloudFormation. The deploy log shows two distinct phases:
- Deploying gateways... — Creates the Gateway and targets via the AgentCore Gateway API. This phase also validates connectivity to the target MCP server
- Deploy to AWS... — Deploys the Runtime (agent) via CloudFormation
Because the Gateway phase validates MCP server connectivity, deployment fails if the target MCP server is unreachable. This is an important constraint — the availability of external MCP servers directly affects deployment success.
After deployment, the Gateway URL appears in the outputs:
✓ Deployed to 'default' (stack: AgentCore-AgentCoreGwTest-default)
Outputs:
McpGatewayMyGatewayUrlOutput: https://agentcoregwtest-my-gateway-XXXXXXXXXX.gateway.bedrock-agentcore.ap-northeast-1.amazonaws.com/mcpVerify Deployment
agentcore status --json{
"success": true,
"projectName": "AgentCoreGwTest",
"targetName": "default",
"targetRegion": "ap-northeast-1",
"resources": [
{
"resourceType": "agent",
"name": "GwAgent",
"deploymentState": "deployed",
"detail": "READY"
},
{
"resourceType": "gateway",
"name": "my-gateway",
"deploymentState": "local-only",
"detail": "1 target"
}
]
}The Gateway's deploymentState shows local-only because Gateways are managed via the AgentCore API, not CloudFormation.
Verifying Tool Calls Through Gateway
Invoke the deployed agent and ask it to use the Exa AI web search tool through the Gateway.
agentcore invoke \
"Search the web for 'AgentCore CLI latest version' and tell me what you find." \
--stream \
--agent GwAgentBased on my web search, I found information about two different "AgentCore CLI" tools:
## 1. AWS AgentCore CLI (Primary Result)
**Latest Version:** v0.3.0-preview.5.1 (Released March 12, 2026)
- **Status:** Preview/Prerelease
- **Repository:** https://github.com/aws/agentcore-cli
- **Language:** TypeScript (97.3%)
- **License:** Apache License 2.0
This is the official CLI for Amazon Bedrock AgentCore, which helps developers
create, develop locally, and deploy AI agents to AWS.The agent connected to Exa AI's MCP server through the Gateway and executed a web search. The agent code contains no web search implementation — the Gateway transparently handles routing and authentication to the backend MCP server.
Local Development with Gateway
According to the CLI docs, agentcore dev automatically injects environment variables for deployed Gateways. Once you've run agentcore deploy to create the Gateway, local development can use the deployed Gateway to call tools.
AGENTCORE_GATEWAY_MY_GATEWAY_URL=https://{gateway-id}.gateway.agentcore.{region}.amazonaws.com
AGENTCORE_GATEWAY_MY_GATEWAY_AUTH_TYPE=NONEGateway env vars are read from deployed-state.json, so they are not available before the first deployment.
Authentication
This article used authorizerType: "NONE" (no authentication) for simplicity. In production, configure inbound authentication (agent → Gateway) with AWS_IAM or CUSTOM_JWT, and outbound authentication (Gateway → target) with oauth or api-key. See the CLI docs for details.
Summary
- Setup order matters — Gateway → target → agent ensures auto-generated Gateway client code. Reverse order requires manual integration. Use
--no-agentto create the project, then add the Gateway before the agent. - Deployment validates target connectivity — The Gateway deployment phase checks that the target MCP server is reachable. Unreachable servers cause deployment failure. Choose reliable endpoints for production.
- Gateway deploys separately from CloudFormation — Gateways are managed via the AgentCore API, while Runtimes use CloudFormation. This is why
agentcore statusshowslocal-onlyfor Gateway deployment state. - Local dev can use deployed Gateways — After the first deploy,
agentcore devauto-injects Gateway environment variables, letting local agents call tools through the deployed Gateway.
Next up: measuring agent quality with LLM-as-a-Judge using the Evaluations feature.
Cleanup
# Remove all resource definitions
agentcore remove all --force
# Delete AWS resources
agentcore deploy -y
# Uninstall CLI (if no longer needed)
npm uninstall -g @aws/agentcore