A lightweight MCP proxy that runs on Amazon Bedrock AgentCore Runtime and exposes tools from an upstream MCP server as a standard MCP server. The upstream MCP server can be any MCP-compatible endpoint, including MCP servers running on AgentCore Runtime, self-hosted MCP servers, or third-party MCP services. This implementation showcases the pattern using an AgentCore Gateway as the upstream server example, but the proxy architecture applies to any MCP server that you want to add custom controls to.
User / Agent → MCP Proxy (AgentCore Runtime) → AgentCore Gateway → Tools
The proxy fetches all tools registered on the gateway at startup, registers them locally via FastMCP, and forwards every tools/call request to the gateway. Clients connect using the standard MCP streamable-http transport.
The proxy supports two authentication modes for the outbound gateway connection:
- IAM (default) — requests are signed with SigV4 using the runtime's IAM role
- JWT — an OAuth access token is obtained from Amazon Cognito (client credentials grant) and sent as a Bearer token
├── agentcore_deploy/ # Deployed to AgentCore Runtime
│ ├── mcp_proxy/
│ │ ├── __init__.py
│ │ └── main.py # The proxy server
│ ├── Dockerfile
│ ├── requirements.txt
│ └── .dockerignore
├── setup_and_deploy.py # Automated deployment script
├── deploy_config.json # Deployment configuration template
├── test_agent.py # Strands agent for testing the proxy
└── README.md
- Python 3.12+
- AWS CLI configured with credentials
- AgentCore CLI (
pip install bedrock-agentcore-starter-toolkit) - Docker
- An AgentCore Gateway with tools registered
Edit deploy_config.json with your values:
{
"agent_name": "my-mcp-proxy",
"gateway_endpoint": "https://<your-gateway>.gateway.bedrock-agentcore.<region>.amazonaws.com/mcp",
"region": "us-east-1",
"iam_role_name": "MCPProxyServerRole",
"auth_mode": "iam"
}For JWT authentication, set auth_mode to "jwt" and provide Cognito details:
{
"auth_mode": "jwt",
"cognito_user_pool_id": "us-east-1_XXXXXXXXX",
"cognito_client_id": "<app-client-id>",
"cognito_client_secret": "<app-client-secret>",
"cognito_domain": "<cognito-domain-prefix>"
}python3 setup_and_deploy.pyThe script will:
- Create an IAM execution role (if it doesn't exist)
- Run
agentcore configureinteractively - Deploy to AgentCore Runtime with the correct environment variables
You can also override config values via CLI flags:
python3 setup_and_deploy.py \
--agent-name my_proxy \
--gateway-endpoint https://<gateway-url>/mcp \
--auth-mode jwtcd agentcore_deploy
agentcore configure --name my_proxy --entrypoint mcp_proxy/main.py \
--execution-role <role-arn> --protocol MCP --requirements-file requirements.txt
agentcore launch --agent my_proxy \
--env GATEWAY_ENDPOINT=https://<gateway-url>/mcp \
--env AUTH_MODE=iamFor JWT mode, add the Cognito environment variables:
agentcore launch --agent my_proxy \
--env GATEWAY_ENDPOINT=https://<gateway-url>/mcp \
--env AUTH_MODE=jwt \
--env COGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX \
--env COGNITO_CLIENT_ID=<client-id> \
--env COGNITO_CLIENT_SECRET=<client-secret> \
--env COGNITO_DOMAIN=<domain-prefix>Update MCP_PROXY_ARN in test_agent.py with your deployed proxy's ARN, then:
pip install strands-agents strands-agents-tools boto3 httpx
python3 test_agent.pyThe agent discovers tools from the proxy and lets you interact with them in a chat loop.
agentcore_deploy/mcp_proxy/main.py does three things:
- On startup, sends a
tools/listJSON-RPC request to the gateway (authenticated via IAM or JWT). - For each tool returned, registers a FastMCP tool that forwards
tools/callto the gateway. - Runs FastMCP with
stateless_http=Trueandtransport="streamable-http".
AgentCore Runtime handles the HTTP ingress and client authorization. The proxy itself is stateless.
| Variable | Required | Default | Description |
|---|---|---|---|
GATEWAY_ENDPOINT |
Yes | — | AgentCore Gateway MCP endpoint URL |
AUTH_MODE |
No | iam |
iam or jwt |
COGNITO_USER_POOL_ID |
When jwt | — | Cognito User Pool ID |
COGNITO_CLIENT_ID |
When jwt | — | OAuth App Client ID |
COGNITO_CLIENT_SECRET |
When jwt | — | OAuth App Client Secret |
COGNITO_DOMAIN |
When jwt | — | Cognito domain prefix for token endpoint |
MIT