I tried building a multi-agent AI Starter with AgentCore Gateway × VPC Lambda

I tried building a multi-agent AI Starter with AgentCore Gateway × VPC Lambda

Leveraging existing MCP integrations to expose VPC Lambda sub-agents as tools via AgentCore Gateway MCP targets. Here's a summary of the steps and pitfalls encountered in achieving a multi-agent configuration without any application code changes.
2026.07.21

This page has been translated by machine translation. View original

Introduction

I encountered a situation where I wanted to add "sub-agents" to AI Starter. This is a multi-agent configuration where a parent agent (assistant) delegates tasks it cannot handle on its own to specialized sub-agents, then incorporates the results to provide an answer.

AI Starter has MCP (Model Context Protocol) integration implemented, with a mechanism for calling external MCP servers as tools. My investigation started from the question: can we leverage this existing MCP integration to add sub-agents?

Can Sub-Agents Be Added to AI Starter?

How MCP Integration Works

Upon investigation, I found that AI Starter's MCP client communicates with remote MCP servers using Streamable HTTP Transport. The flow is simple:

  1. Register the MCP server URL
  2. At startup, retrieve the tool list via tools/list
  3. LLM decides to call a tool → execute via tools/call
  4. Return the result to the LLM's context

In other words, as long as you prepare an endpoint that behaves as an MCP server, the application treats it as "just a tool." Whether the sub-agent's internals call an LLM or use simple logic doesn't matter — as long as it satisfies the MCP interface, it works transparently.

AgentCore Gateway Becomes an MCP Aggregator

This is where Amazon Bedrock AgentCore Gateway comes in. AgentCore Gateway has a feature called MCP targets that wraps Lambda functions as MCP tools.

Architecture diagram:

agentcore-gateway-mcp-multi-agent-vpc-lambda-architecture

Since the Gateway responds to tools/list and exposes Lambda-based sub-agents as tools, no code changes are needed on the application side.

MCP Target vs HTTP Target

AgentCore Gateway has two types: "MCP target" and "HTTP target." Here is an important finding:

MCP Target HTTP Target
Discoverable via tools/list Yes No
Tool schema definition Required (name, description, inputSchema) Not required (pass-through)
Use case Called as a tool API proxy

HTTP targets do not appear in tools/list and are therefore invisible to MCP clients. If you want to use it as a sub-agent, MCP target is the only option.

Building Sub-Agents with VPC Lambda

Add Inbound Rules to the Security Group

Add HTTPS (443) / Source: own SG to the security group's inbound rules. This allows HTTPS communication from Lambda within the same SG to the VPC Endpoint.

  1. VPC Console → Security Groups → Edit Inbound Rules
    SCR-20260717-jfsh (1)

  2. Click Add Rule

  3. Type: HTTPS

  4. Source: Custom

  5. Target: Your own security group ID

  6. Click Save Rules
    SCR-20260717-jgkr (2)

Creating a VPC Endpoint

A VPC Endpoint is required to call Bedrock from Lambda inside a VPC (no NAT Gateway needed).

  1. VPC Console → Endpoints → Create Endpoint

  2. Type: AWS Services
    SCR-20260717-jbzf

  3. Service: com.amazonaws.ap-northeast-1.bedrock-runtime
    SCR-20260717-jcan

  4. Select VPC
    SCR-20260717-jccm (1)

  5. Select subnet
    SCR-20260717-jcfa (1)

  6. Select security group
    SCR-20260717-jcgn (1)

Creating the Lambda Function

Implement the sub-agent with VPC Lambda. Here we use a "summarization agent" as an example.

  • Runtime: Python 3.12
  • VPC: Specify the same VPC, subnet, and SG as the VPC Endpoint
  • Timeout: Set to 30 seconds or more since LLM calls are involved
  • IAM Role: Grant bedrock:InvokeModel permission
  1. Lambda Console → Functions → Create Function
    SCR-20260717-jcrh (1)

  2. Select Author from scratch
    SCR-20260717-jgrv

  3. Enable ARM64 architecture for cost savings

  4. Enable VPC

  5. Select security group

  6. Click the Save button
    SCR-20260717-jgpx (2)

  7. Click Create Function
    SCR-20260717-jgyw (1)

  8. Configure the Lambda function with the following content

lambda_function.py
import boto3
import json

bedrock = boto3.client("bedrock-runtime")

SYSTEM_PROMPT = "You are a summarizer. Summarize the given text concisely in bullet points."

def lambda_handler(event, context):
    text = event.get("text", "")
    response = bedrock.converse(
        modelId="jp.anthropic.claude-haiku-4-5-20251001-v1:0",
        system=[{"text": SYSTEM_PROMPT}],
        messages=[{"role": "user", "content": [{"text": text}]}],
        inferenceConfig={"maxTokens": 2048},
    )
    return {
        "result": response["output"]["message"]["content"][0]["text"]
    }

SCR-20260717-jhmc

  1. Configuration → Permissions → Edit
    SCR-20260717-jikr (1)

  2. Timeout: 1 minute

  3. Select Create a new role
    SCR-20260717-jkph (1)

  4. Create a role with the following content

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "bedrock:InvokeModel",
      "Resource": "*"
    }
  ]
}

SCR-20260717-jjxm (1)

  1. Test → Create new test event
    SCR-20260717-jlch (1)

  2. Invocation type: Synchronous

  3. Events sharing settings: Private

  4. Set the JSON event with the following content

{
  "text": "Amazon Bedrock is a fully managed service that makes foundation models from leading AI companies available through a single API. It offers a broad range of models to choose from, along with capabilities to build generative AI applications with security, privacy, and responsible AI."
}

SCR-20260717-jlju (1)

If the test succeeds, you are good to go.

Setting Up AgentCore Gateway

  1. Bedrock Console → AgentCore → Gateways → Create Gateway

  2. IAM Permissions: Create default role

  3. Target: MCP target
    SCR-20260717-kumu (2)

  4. Target type: Lambda ARN

  5. Lambda ARN: The ARN of the Lambda you created earlier
    SCR-20260717-kuoq (1)

  6. Inline schema (enter in the JSON editor):

[
  {
    "name": "summarize_text",
    "description": "Summarize given text into concise bullet points. Use when user asks to summarize long content.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "text": {
          "type": "string",
          "description": "The text to summarize"
        }
      },
      "required": ["text"]
    }
  }
]

SCR-20260717-kxim (1)

The schema must be written in array format including name and description, not just the inputSchema part. Pasting only inputSchema will result in the following validation error:

Value at 'targetConfiguration.mcp.lambda.toolSchema.inlinePayload.1.member.name'
failed to satisfy constraint: Member must not be null

When using JWT authentication, configure the Amazon Cognito User Pool information:

  • Issuer: https://cognito-idp.ap-northeast-1.amazonaws.com/<USER_POOL_ID>
  • Audience: Cognito App Client ID

Verifying MCP Endpoint Operation

Verify the operation using the MCP endpoint URL issued after Gateway creation.

# Retrieve tool list
curl -X POST \
  https://<GATEWAY_ID>.gateway.bedrock-agentcore.ap-northeast-1.amazonaws.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

If the tools appear in the response, it is successful. The Gateway automatically prepends the target name as a prefix to tool names (e.g., target-xxx___summarize_text).

# Tool execution test
curl -X POST \
  https://<GATEWAY_ID>.gateway.bedrock-agentcore.ap-northeast-1.amazonaws.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"<TARGET_PREFIX>___summarize_text","arguments":{"text":"Test text..."}}}'

SCR-20260717-lpnx (1)

SCR-20260717-lpxg (1)

Building Sub-Agents in AI Starter

Adding an External Service

  1. AI Starter Admin Console → External Services
    SCR-20260717-mhnd

  2. Select Add New
    SCR-20260718-name

  3. Service URL: The URL of the AgentCore Gateway you created earlier
    SCR-20260718-nbmw (1)

Creating a New Assistant (Use Case)

  1. AI Starter Admin Console → Assistants
  2. Select the external service you created earlier as the MCP server
    SCR-20260718-ndqe

Verifying Operation in AI Starter

  1. AI Starter → Use Cases

  2. Select the assistant (use case) you created earlier
    SCR-20260718-nehu (1)

  3. Test the summarization feature you registered
    SCR-20260718-nerc (1)

SCR-20260718-nevt
The registered MCP tool is called.

SCR-20260718-nfaw (1)
The generated content is returned.

Collection of Pitfalls

Here is a summary of issues encountered during the build and their solutions.

1. Cross-Region Inference Profile Routing

Symptom: Using jp.anthropic.claude-haiku-4-5-20251001-v1:0 causes AccessDeniedException even though ap-northeast-1 resources are allowed in the IAM policy.

Cause: Inference profiles with the jp. prefix are internally routed by AWS to the Japan region group (ap-northeast-1, ap-northeast-3, etc.). If only ap-northeast-1 is allowed, access is denied when routed to ap-northeast-3 (Osaka).

Solution: Set the IAM policy Resource to "*" in staging environments. In production, explicitly allow all required regions or use a wildcard like arn:aws:bedrock:*:<ACCOUNT_ID>:inference-profile/*.

2. Inference Profile ARN Format

Symptom: Specifying arn:aws:bedrock:ap-northeast-1::foundation-model/* in the IAM policy causes AccessDeniedException.

Cause: Models with the jp. prefix are inference profiles and use the inference-profile ARN format, not foundation-model. The ARN also requires an account ID.

# NG
arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-*

# OK
arn:aws:bedrock:*:<ACCOUNT_ID>:inference-profile/jp.anthropic.*

3. Marketplace Permissions

Symptom: Lambda unit tests succeed, but going through the Gateway causes AccessDeniedException (related to Marketplace actions).

Cause: aws-marketplace:ViewSubscriptions and aws-marketplace:Subscribe permissions may be required on the first invocation of Anthropic models. As of July 2026, Bedrock model access is automatically enabled, but Marketplace integration permissions are required separately.

Solution: Add the following policy to the Lambda IAM role.

{
  "Effect": "Allow",
  "Action": [
    "aws-marketplace:ViewSubscriptions",
    "aws-marketplace:Subscribe"
  ],
  "Resource": "*"
}

4. Gateway Target Schema Validation

Symptom: inlinePayload.1.member.name failed to satisfy constraint: Member must not be null when adding a target.

Cause: There are two patterns.

  1. Only inputSchema was pasted in the inline schema without including name / description
  2. An empty tool row remains in the console form (index 1 = the second row is empty)

Solution: Write in the array format [{name, description, inputSchema}] and confirm there are no empty rows.

5. Gateway IAM Role Propagation Delay

Symptom: Adding a target immediately after Gateway creation results in Gateway service is not authorized to perform AssumeRole on Gateway role.

Cause: Immediately after IAM role creation, it may take tens of seconds to propagate within AWS internally.

Solution: Wait about 30 seconds and retry.

Summary

By leveraging the MCP target of AgentCore Gateway, we were able to achieve a multi-agent configuration without modifying existing application code.

Key Points of the Configuration:

  • Leverage existing MCP integration by simply registering the Gateway as an "MCP server"
  • Sub-agents implemented with VPC Lambda + Bedrock (via VPC Endpoint, no NAT required)
  • Gateway intermediates the MCP protocol and transparently handles tool discovery (tools/list) and execution (tools/call)
  • Sub-agents can be scaled out by adding more MCP targets

Practical Decision Criteria:

  • Prepare a dedicated Lambda for each sub-agent and specialize its role with a system prompt
  • Gateway authentication can be None for MVP, but JWT (Cognito) is recommended for production
  • When using VPC Lambda, don't forget to configure the VPC Endpoint security group settings
  • In IAM policies, pay attention to the inference profile ARN format and cross-region routing

Share this article

AWSのお困り事はクラスメソッドへ