AI 日报hiw3c.com

Build a multi-account AI agent with AgentCore Gateway and MCP

AWS ML Blog aws.amazon.com RSS 全文
正文为英文,可一键机器翻译(仅首次需要等待)

Enterprises increasingly want AI agents that can reason over data spread across many AWS accounts without copying or centralizing it. Each team keeps its data in its own account for good reasons: clear ownership, scope isolation, and independent deployment lifecycles. But an agent that sees only one account’s data delivers limited value, and connecting it to distributed sources usually means replicating data or untangling cross-account AWS Identity and Access Management (IAM). The goal is to let data stay where it already lives, in each line-of-business (LOB) account. Only the specific data a request needs flows out at query time, so the underlying datasets do not leave their owning account.

In this post, you build a multi-account architecture that keeps each team’s data in its own account while giving agents a unified way to query across them, using Amazon Bedrock AgentCore Gateway and Model Context Protocol (MCP). Amazon Bedrock AgentCore is an agentic service for building, deploying, and operating highly effective agents securely at scale. A central platform account hosts the agent tier and large language model (LLM) inference through Amazon Bedrock. LOB teams expose their data and tools as MCP servers, and the platform account’s AgentCore Gateway gives agents a single endpoint for tool discovery and invocation across registered LOBs. Along the way, you set up cross-account MCP integration, authentication with AgentCore Identity, a capability of Amazon Bedrock AgentCore, and Okta, fine-grained authorization with Policy in Amazon Bedrock AgentCore, and the governance controls that support production readiness.

Solution overview

The architecture follows a multi-account model with three layers: a central platform account, distributed LOB accounts, and AgentCore Gateway as the integration layer that connects them.

Platform account — the agent control plane

The platform team owns the platform account, which runs the agent on AgentCore Runtime, a capability of Amazon Bedrock AgentCore. AgentCore Runtime is a serverless, framework-agnostic environment with session isolation in dedicated microVMs, consumption-based pricing, and built-in authentication. To keep the walkthrough clear, this post uses a single agent, but the same pattern supports multiple agents in the platform account. The agent connects to the platform account’s Gateway rather than to individual LOB MCP servers.

LLM inference runs in the platform account through Amazon Bedrock. The platform team controls available foundation models (FMs), applies Amazon Bedrock Guardrails, and tracks costs through a single billing boundary, avoiding the overhead of managing model quotas across dozens of LOB accounts. As demand grows, some organizations distribute inference across several dedicated inference accounts, placing AgentCore Gateway in front as an Inference Gateway that routes traffic across model providers, selecting the provider based on the request and applying per-team rate limits.

AgentCore Gateway in the platform account acts as the single MCP endpoint for the agent. It registers each LOB account’s MCP server as a target and, from that one endpoint, provides unified tool discovery with semantic search, centralized authentication through AgentCore Identity, fine-grained authorization with Policy in AgentCore, and observability.

Beyond aggregating MCP servers and acting as an Inference Gateway, AgentCore Gateway supports additional target types that make it a central integration point. HTTP targets bring AgentCore Runtime agents, agent-to-agent (A2A) services, and other HTTP endpoints into the same governed endpoint, each addressable through its own sub-path. The platform team can also apply Amazon Bedrock Guardrails for content safety and configure Policy in AgentCore (Cedar) for fine-grained access control, both enforced at the Gateway layer outside the agent’s code.

LOB accounts — data and tools

Rather than exposing raw AWS resources (Amazon Simple Storage Service (Amazon S3) buckets, databases, Amazon Bedrock Knowledge Bases) directly, each LOB team packages its data and tools as an MCP server. The retail banking team exposes tools like get_balance and get_profile. The lending team offers get_credit_score and search_lending_policies, where the latter queries the fully managed Retrieval Augmented Generation (RAG) capability in Amazon Bedrock Knowledge Bases over bank policy PDFs. This reference architecture wraps a standalone Amazon Bedrock Knowledge Base inside the MCP server for fine-grained control over the retrieval pipeline. For new implementations, you can instead attach an Amazon Bedrock Managed Knowledge Base directly to the Gateway as a native connector, so agents query it with standard MCP calls and you operate no retrieval infrastructure.

The MCP server runs on AgentCore Runtime in the LOB account, a serverless, framework-agnostic environment with session isolation in dedicated microVMs, consumption-based pricing, built-in authentication through AgentCore Identity, and agent-specific observability. This gives LOB teams full ownership of their tool surface: they decide what to expose and what business logic runs behind each tool, and can change the implementation without affecting the platform agent, as long as the MCP tool interface stays consistent.

Cross-account integration: Gateway and Identity connect the layers

This architecture follows a hub-and-spoke pattern: each LOB deploys a standalone MCP server (the spoke) using MCP over Streamable HTTP, while AgentCore Gateway (the hub) aggregates them behind a single endpoint. The agent connects to the Gateway as one MCP server, and the Gateway federates tool invocation across registered LOB targets. When the agent invokes a tool, the Gateway retrieves OAuth 2.0 machine-to-machine (M2M) credentials from AgentCore Identity, attaches them to the outbound request, and routes it to the right LOB MCP server, which authenticates the token against Okta’s OpenID Connect (OIDC) endpoint before processing the request locally.

The LOB’s data stays in its own account: the MCP server returns only the specific result the tool produced, not the raw dataset, and that result flows to the platform account as context for inference. The source data isn’t copied or relocated.

Multi-account AI agent architecture with AgentCore Gateway, MCP servers, and Cedar policy authorization across platform and LOB accounts.

Figure 1: Multi-account AI agent architecture with AgentCore Gateway and MCP

The following walkthrough traces a user’s question as it crosses account boundaries, invokes distributed tools, and returns a unified answer:

  1. The user logs in through the React webapp, which redirects to Okta for authentication.
  2. Okta validates the user’s credentials and returns a JSON Web Token (JWT) containing identity claims (sub, groups, audience).
  3. The user submits a prompt through the webapp, which reaches Amazon CloudFront over HTTPS.
  4. CloudFront forwards the request to the FastAPI backend running on Amazon Elastic Container Service (Amazon ECS) with AWS Fargate.
  5. The backend applies Amazon Bedrock Guardrails for personally identifiable information (PII) redaction on the user’s input before it reaches the agent, and again on the agent’s output before it reaches the user.
  6. The backend invokes the Strands Agent on AgentCore Runtime, forwarding the user’s JWT in the Authorization header for identity propagation.
  7. The agent sends the prompt to Amazon Bedrock for reasoning. Based on the model’s response, the agent determines which tools to invoke.
  8. The agent forwards the user’s JWT to AgentCore Gateway, which uses semantic search for tool discovery across LOB targets. Policy in AgentCore (when a policy engine is associated with the Gateway) evaluates the JWT claims against Cedar rules and permits or denies each tool call by user identity, role, or action. Because the outbound call uses M2M, user-level authorization is enforced here at the Gateway.
  9. For permitted calls, the Gateway retrieves OAuth 2.0 M2M credentials from AgentCore Identity, attaches them to the outbound request, and forwards it to the correct LOB MCP server. Each LOB MCP server validates the inbound OAuth token before processing.
  10. The LOB MCP server runs its tool logic: (a) against local Amazon DynamoDB tables for structured data lookups, and (b) for the Lending & Wealth LOB, also performs RAG retrieval against Amazon Bedrock Knowledge Bases over bank policy PDFs stored in Amazon S3 with Amazon OpenSearch Serverless indexing.

Results flow back through the same chain (LOB to Gateway to Agent to backend), with a trace panel in the sample application showing which LOBs were accessed and Policy in AgentCore denials. Each LOB runtime validates the inbound OAuth token. In production, the LOB team configures allowedWorkloadConfiguration to restrict runtime invocation to requests whose identity chain includes the Gateway, reducing the risk of direct access that bypasses Gateway policy and Cedar authorization.

The Strands Agent discovers LOB tools through the Gateway’s tools/list method, and queries AWS Agent Registry (Preview) at startup to discover registered LOB MCP servers. Onboarding a new LOB involves adding a Gateway target. The agent discovers the new tools on its next tools/list call.

Technical implementation

The following sections walk through each layer of the architecture: how LOB teams build and deploy MCP servers, how the platform team configures AgentCore Gateway with OAuth outbound authentication and Policy in AgentCore authorization, and how continuous evaluation helps keep the agent reliable as tools and models evolve. For the complete implementation, clone the accompanying repository and run the deployment script, which bootstraps AWS Cloud Development Kit (AWS CDK) across the four accounts, provisions the platform and LOB resources, deploys the MCP servers and Gateway targets, and launches a React web application on Amazon ECS behind CloudFront.

Prerequisites

The accompanying repository assumes the following:

  • An AWS multi-account setup managed through AWS Organizations, with the platform and LOB accounts in the same organization.
  • Amazon Bedrock model access in the platform account.
  • AgentCore configured in both the platform account (for the agent, Gateway, and Registry) and each LOB account (for MCP server hosting on Runtime).
  • An OIDC-compatible identity provider (such as Okta, Amazon Cognito, or Microsoft Entra ID) with M2M app clients for the OAuth 2.0 client credentials grant. The repository uses Okta.
  • LOB data sources (Amazon Bedrock Knowledge Bases, Amazon DynamoDB tables, Amazon S3 buckets, or API endpoints) that the MCP servers will wrap.

Set up MCP servers in the LOB accounts

Each LOB team builds an MCP server with FastMCP and deploys it to AgentCore Runtime using the AgentCore CLI, exposing the team’s data as structured tools with typed inputs and outputs. Each LOB team configures its server with a customJWTAuthorizer that authenticates inbound OAuth tokens against Okta’s OIDC discovery endpoint, so requests must present a valid token before they can invoke the LOB’s tools. For production hardening, set allowedWorkloadConfiguration on the Runtime to the Gateway’s Amazon Resource Name (ARN), which configures it to accept requests only when the identity chain includes that Gateway. This sample relies on OAuth audience validation as its primary access control. Adding allowedWorkloadConfiguration helps restrict invocations to those arriving through the Gateway, reducing the risk of direct access that bypasses Gateway policy.

This snippet shows the Lending & Wealth LOB’s MCP server, combining Amazon DynamoDB lookups with Amazon Bedrock Knowledge Bases retrieval.

REGION = os.environ.get("AWS_REGION", "us-east-1")
dynamodb = boto3.resource("dynamodb", region_name=REGION)
bedrock_agent_runtime = boto3.client("bedrock-agent-runtime", region_name=REGION)
KNOWLEDGE_BASE_ID = os.environ.get("KNOWLEDGE_BASE_ID", "")

mcp = FastMCP("lending-wealth", host="0.0.0.0", stateless_http=True)


@mcp.tool()
def get_credit_score(customer_id: str) -> dict:
    """Get credit score and contributing factors for a customer."""
    table = dynamodb.Table("CreditScores")
    resp = table.get_item(Key={"customer_id": customer_id})
    item = resp.get("Item")
    if not item:
        return {"error": f"No credit score found for customer {customer_id}"}
    return item


@mcp.tool()
def search_lending_policies(query: str) -> str:
    """Search the bank's lending policy documents for guidelines,
    eligibility criteria, and regulatory requirements."""
    if not KNOWLEDGE_BASE_ID:
        return json.dumps({"error": "KNOWLEDGE_BASE_ID not configured"})
    resp = bedrock_agent_runtime.retrieve(
        knowledgeBaseId=KNOWLEDGE_BASE_ID,
        retrievalQuery={"text": query},
        retrievalConfiguration={"vectorSearchConfiguration": {"numberOfResults": 5}},
    )
    chunks = []
    for r in resp.get("retrievalResults", []):
        text = r.get("content", {}).get("text", "")
        source = r.get("location", {}).get("s3Location", {}).get("uri", "")
        if text:
            chunks.append({"text": text, "source": os.path.basename(source)})
    return json.dumps({"results": chunks}, default=str)


if __name__ == "__main__":
    mcp.run(transport="streamable-http")

Deploy the MCP server to AgentCore Runtime with the AgentCore CLI. The configure step sets the entrypoint and protocol. The deploy step packages and pushes it:

# Configure the MCP server
agentcore configure \
    --entrypoint server.py \
    --name lending_wealth_mcp \
    --protocol MCP \
    --disable-memory \
    --non-interactive \
    --authorizer-config '{
      "customJWTAuthorizer": {
        "discoveryUrl": "<OKTA_DISCOVERY_URL>",
        "allowedAudience": ["lobfederation"]
      }
    }'

# Deploy to AgentCore Runtime
agentcore deploy --auto-update-on-conflict \
    --env KNOWLEDGE_BASE_ID=<your-knowledge-base-id>

After deployment, the CLI returns a runtime ARN that the platform team uses to register the MCP server as a Gateway target.

Configure AgentCore Gateway

In the platform account, create the Gateway with a Custom JWT authorizer that points to Okta’s OIDC discovery URL and validates the audience (aud) claim to restrict which applications can connect:

ctrl.update_gateway(
    gatewayIdentifier=gateway_id,
    name="lobfederation-gateway",
    protocolType="MCP",
    protocolConfiguration={
        "mcp": {
            "searchType": "SEMANTIC",
            "supportedVersions": ["2025-03-26"],
        }
    },
    authorizerType="CUSTOM_JWT",
    authorizerConfiguration={
        "customJWTAuthorizer": {
            "discoveryUrl": "https://<your-okta-domain>/oauth2/<auth-server-id>/.well-known/openid-configuration",
            "allowedAudience": ["lobfederation"],
        }
    },
)

For outbound authentication to LOB MCP servers, the Gateway uses the OAuth 2.0 client credentials grant (M2M). The platform team registers an OAuth credential provider in AgentCore Identity that stores the Okta M2M client credentials. When the Gateway invokes a LOB MCP server, AgentCore Identity obtains a fresh access token from Okta and passes it in the Authorization hea